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
140 function Field() {
141 $pattern = $this->getValidationRegexp();
142
143 $pattern = preg_replace("/^\//", "", $pattern);
144 $pattern = preg_replace("/\/$/", "", $pattern);
145 $this->setHTML5Attribute('pattern', $pattern);
146 return parent::Field();
147 }
148
149 150 151 152 153
154 function getValidationRegexp() {
155 $max = $this->getMaxLength() - strlen($this->getFixedPart());
156 $min = max($this->getMinLength() - strlen($this->getFixedPart()), 0);
157 $min = min($min, $max);
158 return sprintf("/^\+?%s\d{%d,%d}$/", preg_quote(str_replace('+','', $this->getFixedPart())), $min, $max);
159 }
160
161 function jsValidation() {
162 $formID = $this->form->FormName();
163 $error = _t('PhoneField.VALIDATIONJS', 'Please enter correct phone.');
164 $regexp = $this->getValidationRegexp();
165
166 $jsFunc =<<<JS
167 Behaviour.register({
168 "#$formID": {
169 validatePhoneField: function(fieldName) {
170 var el = _CURRENT_FORM.elements[fieldName];
171 if(!el || !el.value) return true;
172 var val = el.value.replace(/[^0-9+]+/g, '');
173 if(val.match({$regexp})) {
174 return true;
175 } else {
176 validationError(el, "$error","validation");
177 return false;
178 }
179 }
180 }
181 });
182 JS;
183
184 Requirements::customScript($jsFunc, 'func_validatePhoneField' .'_' . $formID);
185
186 return <<<JS
187 if(typeof fromAnOnBlur != 'undefined'){
188 if(fromAnOnBlur.name == '$this-me')
189 $('$formID').validatePhoneField('$this-me');
190 }else{
191 $('$formID').validatePhoneField('$this->name');
192 }
193 JS;
194 }
195
196 function validate($validator){
197 $this->value = self::cleanup_phone($this->value);
198 if ($this->value && !preg_match($this->getValidationRegexp(), $this->value)){
199 if ($validator) {
200 $validator->validationError(
201 $this->name,
202 _t('PhoneField.VALIDATION', "Please enter correct phone."),
203 "validation"
204 );
205 }
206 return false;
207 }
208 else {
209 return parent::validate($validator);
210 }
211 }
212
213 214 215 216 217 218
219 function dataValue() {
220 return self::cleanup_phone($this->value);
221 }
222 }
223
[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.
-