1 <?php
2 3 4 5 6
7 class PhoneField extends TextField {
8
9 protected static $fixed_part = '';
10
11 12 13 14 15
16 static function set_fixed_part($part) {
17 self::$fixed_part = $part;
18 }
19
20 protected static $max_length = 15;
21
22 23 24 25 26
27 static function set_max_length($val) {
28 self::$max_length = $val;
29 }
30
31 protected static $min_length = 3;
32
33 34 35 36 37
38 static function set_min_length($val) {
39 self::$min_length = $val;
40 }
41
42
43 static $value_searches = array(
44 '/[^\d+]+/',
45
46 );
47
48 static $value_replaces = array(
49 '',
50
51 );
52
53 54 55 56 57 58
59 static function add_replace($from, $to) {
60 self::$value_searches[] = $from;
61 self::$value_replaces[] = $to;
62 }
63
64 65 66 67 68 69
70 static function set_replaces($from, $to) {
71 self::$value_searches = $from;
72 self::$value_replaces = $to;
73 }
74
75
76 77 78 79 80 81 82
83 static function cleanup_phone($val) {
84 $val = trim($val);
85 if (count(self::$value_searches) > 0 && count(self::$value_searches) == count(self::$value_replaces)) {
86 return preg_replace(self::$value_searches, self::$value_replaces, $val);
87 }
88 return $val;
89 }
90
91
92 protected $fixedPart = false;
93
94
95 protected $minLength = false;
96
97 function setFixedPart($value) {
98 $this->fixedPart = $value;
99 if (!$this->value || ($this->value == self::$fixed_part))
100 $this->setValue($value);
101 }
102
103 104 105 106 107
108 function getFixedPart() {
109 if ($this->fixedPart !== false) {
110 return $this->fixedPart;
111 }
112 return self::$fixed_part;
113 }
114
115 function setMinLength($val) {
116 $this->minLength = $val;
117 }
118
119 function getMinLength() {
120 if ($this->minLength !== false) {
121 return $this->minLength;
122 }
123 return self::$min_length;
124 }
125
126 function __construct($name, $title = null, $value = "", $maxLength = null, $form = null){
127 if (!$value) {
128 $value = $this->getFixedPart();
129 }
130 if (!$maxLength) {
131 $maxLength = self::$max_length;
132 }
133
134 $this->setHTML5Attribute('type', 'tel');
135 $this->setAutocomplete('tel');
136
137 parent::__construct($name, $title, $value, $maxLength, $form);
138
139 $pattern = $this->getValidationRegexp();
140 $this->setFieldPattern($pattern);
141 }
142
143 function setFieldPattern($pattern) {
144
145 $pattern = preg_replace("/^\//", "", $pattern);
146 $pattern = preg_replace("/\/$/", "", $pattern);
147 $this->setHTML5Attribute('pattern', $pattern);
148 }
149
150 function getFieldPattern($withSlashes=false) {
151 $pattern = $this->getHTML5Attribute('pattern');
152 return ($withSlashes ? "/{$pattern}/" : $pattern);
153 }
154
155 156 157 158 159
160 function getValidationRegexp() {
161 $max = $this->getMaxLength() - strlen($this->getFixedPart());
162 $min = max($this->getMinLength() - strlen($this->getFixedPart()), 0);
163 $min = min($min, $max);
164 return sprintf("/^\+?%s\d{%d,%d}$/", preg_quote(str_replace('+','', $this->getFixedPart())), $min, $max);
165 }
166
167 function jsValidation() {
168 $formID = $this->form->FormName();
169 $error = _t('PhoneField.VALIDATIONJS', 'Please enter correct phone.');
170 $regexp = $this->getFieldPattern(true);
171
172 $jsFunc =<<<JS
173 Behaviour.register({
174 "#$formID": {
175 validatePhoneField: function(fieldName) {
176 var el = _CURRENT_FORM.elements[fieldName];
177 if(!el || !el.value) return true;
178 var val = el.value.replace(/[^0-9+]+/g, '');
179 if(val.match({$regexp})) {
180 return true;
181 } else {
182 validationError(el, "$error","validation");
183 return false;
184 }
185 }
186 }
187 });
188 JS;
189
190 Requirements::customScript($jsFunc, 'func_validatePhoneField' .'_' . $formID);
191
192 return <<<JS
193 if(typeof fromAnOnBlur != 'undefined'){
194 if(fromAnOnBlur.name == '$this-me')
195 $('$formID').validatePhoneField('$this-me');
196 }else{
197 $('$formID').validatePhoneField('$this->name');
198 }
199 JS;
200 }
201
202 function validate($validator){
203 if ($this->value && !preg_match($this->getFieldPattern(true), $this->value)){
204 if ($validator) {
205 $validator->validationError(
206 $this->name,
207 _t('PhoneField.VALIDATION', "Please enter correct phone."),
208 "validation"
209 );
210 }
211 return false;
212 } else {
213 return parent::validate($validator);
214 }
215 }
216
217 218 219 220 221 222
223 function dataValue() {
224 return self::cleanup_phone($this->value);
225 }
226 }
227
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-