Version: current

      1 <?php
      2
      3 /**
      4  * @package forms
      5  * @subpackage fields-formattedinput
      6  */
      7
      8 /**
      9  * Field for displaying phone numbers. It separates the number, the area code and optionally the country code
     10  * and extension.
     11  * @package forms
     12  * @subpackage fields-formattedinput
     13  */
     14 class PhoneNumberField extends FormField {
     15
     16     protected $areaCode;
     17     protected $countryCode;
     18     protected $ext;
     19
     20     public function __construct( $name, $title = null, $value = '', $extension = null,
     21         $areaCode = null, $countryCode = null, $form = null ) {
     22
     23         $this->areaCode = $areaCode;
     24         $this->ext = $extension;
     25         $this->countryCode = $countryCode;
     26
     27         parent::__construct( $name, $title, $value, $form );
     28     }
     29
     30     public function Field() {
     31         $field = new FieldGroup( $this->name );
     32         $field->setID("{$this->name}_Holder");
     33
     34
     35         list( $countryCode, $areaCode, $phoneNumber, $extension ) = $this->parseValue();
     36
     37         $hasTitle = false;
     38
     39         if ($this->value=="")
     40         {
     41             $countryCode=$this->countryCode;
     42             $areaCode=$this->areaCode;
     43             $extension=$this->ext;
     44         }
     45
     46         if( $this->countryCode !== null )
     47             $field->push( new NumericField( $this->name.'[Country]', '+', $countryCode, 4 ) );
     48
     49         if( $this->areaCode !== null ){
     50             $field->push( new NumericField( $this->name.'[Area]', '(', $areaCode, 4 ) );
     51             $field->push( new NumericField( $this->name.'[Number]', ')', $phoneNumber, 10 ) );
     52         }else{
     53             $field->push( new NumericField( $this->name.'[Number]', '', $phoneNumber, 10 ) );
     54         }
     55
     56         if( $this->ext !== null )
     57             $field->push( new NumericField( $this->name.'[Extension]', 'ext', $extension, 6 ) );
     58
     59         return $field;
     60     }
     61
     62     public function setValue( $value ) {
     63         $this->value = self::joinPhoneNumber( $value );
     64         return $this;
     65     }
     66
     67     public static function joinPhoneNumber( $value ) {
     68         if( is_array( $value ) ) {
     69             $completeNumber = '';
     70             if( isset($value['Country']) && $value['Country']!=null) {
     71                 $completeNumber .= '+' . $value['Country'];
     72             }
     73
     74             if( isset($value['Area']) && $value['Area']!=null) {
     75                 $completeNumber .= '(' . $value['Area'] . ')';
     76             }
     77
     78             $completeNumber .= $value['Number'];
     79
     80             if( isset($value['Extension']) && $value['Extension']!=null) {
     81                 $completeNumber .= '#' . $value['Extension'];
     82             }
     83
     84             return $completeNumber;
     85         } else
     86             return $value;
     87     }
     88
     89     protected function parseValue() {
     90         if( !is_array( $this->value ))
     91             preg_match( '/^(?:(?:\+(\d+))?\s*\((\d+)\))?\s*([0-9A-Za-z]*)\s*(?:[#]\s*(\d+))?$/', $this->value, $parts );
     92         else
     93             return array( '', '', $this->value, '' );
     94
     95         if(is_array($parts)) array_shift( $parts );
     96
     97         for ($x=0;$x<=3;$x++) {
     98             if (!isset($parts[$x])) $parts[]='';
     99         }
    100
    101         return $parts;
    102     }
    103
    104     public function saveInto( $record ) {
    105
    106         list( $countryCode, $areaCode, $phoneNumber, $extension ) = $this->parseValue();
    107         $fieldName = $this->name;
    108
    109         $completeNumber = '';
    110
    111         if( $countryCode )
    112             $completeNumber .= '+' . $countryCode;
    113
    114         if( $areaCode )
    115             $completeNumber .= '(' . $areaCode . ')';
    116
    117         $completeNumber .= $phoneNumber;
    118
    119         if( $extension )
    120             $completeNumber .= '#' . $extension;
    121
    122         $record->$fieldName = $completeNumber;
    123     }
    124
    125     /**
    126      * @todo Very basic validation at the moment
    127      */
    128     function jsValidation() {
    129         $formID = $this->form->FormName();
    130
    131         $jsFunc =<<<JS
    132 Behaviour.register({
    133     "#$formID": {
    134         validatePhoneNumber: function(fieldName) {
    135             if(!$(fieldName + "_Holder")) return true;
    136
    137             // Phonenumbers are split into multiple values, so get the inputs from the form.
    138             var parts = $(fieldName + "_Holder").getElementsByTagName('input');
    139             var isNull = true;
    140
    141             // we're not validating empty fields (done by requiredfields)
    142             for(i=0; i < parts.length ; i++ ) {
    143                 isNull = (parts[i].value == null || parts[i].value == "") ? isNull && true : false;
    144             }
    145
    146             if(!isNull) {
    147                 // Concatenate the string values from the parts of the input.
    148                 var joinedNumber = "";
    149                 for(i=0; i < parts.length; i++) joinedNumber += parts[i].value;
    150                 if(!joinedNumber.match(/^[0-9\+\-\(\)\s\#]*\$/)) {
    151                     // TODO Find a way to mark multiple error fields
    152                     validationError(
    153                         fieldName+"-Number",
    154                         "Please enter a valid phone number",
    155                         "validation",
    156                         false
    157                     );
    158                 }
    159             }
    160             return true;
    161         }
    162     }
    163 });
    164 JS;
    165         Requirements :: customScript($jsFunc, 'func_validatePhoneNumber');
    166
    167         return "\$('$formID').validatePhoneNumber('$this->name');";
    168     }
    169
    170     /**
    171      * @todo Very basic validation at the moment
    172      */
    173     function validate($validator){
    174         $valid = preg_match(
    175             '/^[0-9\+\-\(\)\s\#]*$/',
    176             $this->joinPhoneNumber($this->value)
    177         );
    178
    179         if(!$valid){
    180             $validator->validationError(
    181                 $this->name,
    182                 _t('PhoneNumberField.VALIDATION', "Please enter a valid phone number"),
    183                 "validation",
    184                 false
    185             );
    186             return false;
    187         }
    188
    189         return true;
    190     }
    191 }
    192 ?>

[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. -