Passed
Push — master ( 0374f0...9ff869 )
by Thomas
13:12
created

CountryPhoneField::setIsMobile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace LeKoala\PhoneNumber;
4
5
use Exception;
6
use SilverStripe\Forms\FieldGroup;
7
use libphonenumber\PhoneNumberFormat;
8
use SilverStripe\Forms\DropdownField;
9
use SilverStripe\ORM\DataObject;
10
11
/**
12
 * A country/phone combo field
13
 * You might want to use https://github.com/lekoala/silverstripe-form-elements/blob/master/src/TelInputField.php instead
14
 */
15
class CountryPhoneField extends FieldGroup
16
{
17
    const COUNTRY_CODE_FIELD = "CountryCode";
18
    const NUMBER_FIELD = 'Number';
19
    /**
20
     * @var int
21
     */
22
    protected $dataformat = 0; // E164, see libphonenumber/PhoneNumberFormat
23
24
    /**
25
     * @param string $name
26
     * @param string|null $title
27
     * @param mixed $value
28
     */
29
    public function __construct($name, $title = null, $value = null)
30
    {
31
        $country = new DropdownField($name . "[" . self::COUNTRY_CODE_FIELD . "]", "");
32
        $country->setSource(PhoneHelper::getCountriesList());
33
        $country->setHasEmptyDefault(true);
34
        $country->setAttribute('style', 'max-width:166px'); // Match FieldGroup min width
35
        $country->setAttribute('size', 1); // fix some weird sizing issue in cms
36
37
        $number = new PhoneField($name . "[" . self::NUMBER_FIELD . "]", "");
38
        $number->setAttribute('data-value', $value);
39
        // We can use a national friendly format because it's next to the country
40
        $number->setDisplayFormat(PhoneNumberFormat::NATIONAL);
41
42
        parent::__construct($title, $country, $number);
43
44
        $this->name = $name;
45
    }
46
47
    public function hasData()
48
    {
49
        // Turn this into a datafield
50
        return true;
51
    }
52
53
    /**
54
     * @return DropdownField
55
     */
56
    public function getCountryField()
57
    {
58
        return $this->fieldByName($this->name . "[" . self::COUNTRY_CODE_FIELD . "]");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fieldByName($this...UNTRY_CODE_FIELD . ']') targeting SilverStripe\Forms\CompositeField::fieldByName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
59
    }
60
61
    /**
62
     * @return PhoneField
63
     */
64
    public function getPhoneField()
65
    {
66
        return $this->fieldByName($this->name . "[" . self::NUMBER_FIELD . "]");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fieldByName($this...lf::NUMBER_FIELD . ']') targeting SilverStripe\Forms\CompositeField::fieldByName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
67
    }
68
69
    /**
70
     * @return int
71
     */
72
    public function getDataFormat()
73
    {
74
        return $this->dataformat;
75
    }
76
77
    /**
78
     * @param int $v Any of the libphonenumber/PhoneNumberFormat constant
79
     * @return $this
80
     */
81
    public function setDataFormat($v)
82
    {
83
        $this->dataformat = $v;
84
        return $this;
85
    }
86
87
    /**
88
     * @param mixed $value Either the parent object, or array of source data being loaded
89
     * @param array<mixed>|DataObject|null $data {@see Form::loadDataFrom}
90
     * @return $this
91
     */
92
    public function setValue($value, $data = null)
93
    {
94
        $this->fieldByName($this->name . "[" . self::NUMBER_FIELD . "]")->setAttribute('data-value', $value);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->fieldByName($this...lf::NUMBER_FIELD . ']') targeting SilverStripe\Forms\CompositeField::fieldByName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
95
96
        // An array of value to assign to sub fields
97
        if (is_array($value)) {
98
            $countryCode = $value[self::COUNTRY_CODE_FIELD] ?? null;
99
            $number = $value[self::NUMBER_FIELD] ?? null;
100
            if ($countryCode) {
101
                $this->getCountryField()->setValue($countryCode);
102
            }
103
            if ($number) {
104
                $this->getPhoneField()->setValue($number);
105
                $this->getPhoneField()->setCountryCode($countryCode);
106
            }
107
            return $this;
108
        }
109
        // It's an international number
110
        if (strpos((string)$value, '+') === 0) {
111
            $util = PhoneHelper::getPhoneNumberUtil();
112
            try {
113
                $number = $util->parse($value);
114
                $regionCode = $util->getRegionCodeForNumber($number);
115
                $this->getCountryField()->setValue($regionCode);
116
                $phone = $util->format($number, PhoneNumberFormat::NATIONAL);
117
                $this->getPhoneField()->setValue($phone);
118
            } catch (Exception $ex) {
119
                // We were unable to parse, simply set the value as is
120
                $this->getPhoneField()->setValue($value);
121
            }
122
        } else {
123
            $this->getPhoneField()->setValue($value);
124
        }
125
        return $this;
126
    }
127
128
    /**
129
     * Value in E164 format (no formatting)
130
     *
131
     * @return string
132
     */
133
    public function dataValue()
134
    {
135
        $countryValue = $this->getCountryField()->Value();
136
        $phoneValue = $this->getPhoneField()->Value();
137
        if (!$phoneValue) {
138
            return '';
139
        }
140
        if (!$countryValue && strpos((string)$phoneValue, '+') !== 0) {
141
            return $phoneValue;
142
        }
143
144
        $util = PhoneHelper::getPhoneNumberUtil();
145
146
        try {
147
            $number = $util->parse($phoneValue, $countryValue);
148
            $format = $this->dataformat;
149
            return $util->format($number, $format);
150
        } catch (Exception $ex) {
151
            // We were unable to parse, simply return the value as is
152
            return $phoneValue;
153
        }
154
    }
155
156
    /**
157
     * Get the value of isMobile
158
     * @return bool
159
     */
160
    public function getIsMobile()
161
    {
162
        return $this->getPhoneField()->getIsMobile();
163
    }
164
165
    /**
166
     * Set the value of isMobile
167
     *
168
     * @param bool $isMobile
169
     * @return $this
170
     */
171
    public function setIsMobile(bool $isMobile)
172
    {
173
        $this->getPhoneField()->setIsMobile($isMobile);
174
        return $this;
175
    }
176
}
177