A very Basic way to validate Telephone Numbers

A very Basic way to validate Telephone Numbers

Dirk FincleyDirk Fincley Posts: 38Questions: 3Answers: 0
edited March 2016 in Free community support

Telephone numbers are complex to fully validate and they can be represented in many different formats. Also, they may (or may not) be entered with an international country prefix ("00" and then country code) and the rules may change from time to time. However we should not give up because something is hard. This a "rough and ready" method to perform at least some validation of a telephone number in Datatables/Editor.

To simplify matters and avoid having to deal with a multitude of ways to "punctuate" these we can simply insist they are numeric by using the built in "validator ( 'Validate::numeric' )"

We can also is we want use the "validator ( 'Validate::notEmpty' )" to ensure that the user enters a number. Obvioulsy we need to decide if they will always have the number to hand etc.

Then are we need to concern ourselves with is the size of the telephone number. According to Google the minimum international number is 7 digits long. The longest is 15 digits long. Here I check for a "00" prefix. If there is one then the number could involve 15 digits. Otherwise it not does not have the international "00" prefix or the country code and therefore cannot exceed 11 digits.

Here is an example of what a PHP snippet may look like showing the telephone validation logic.

    ->fields(
        Field::inst( 'agent.id' )
            ->validator( 'Validate::notEmpty' ),
        Field::inst( 'agent.first_name' )
            ->validator( 'Validate::notEmpty' ),
        Field::inst( 'agent.surname' )
            ->validator( 'Validate::notEmpty' ),
        Field::inst( 'agent.email' )
            ->validator( 'Validate::notEmpty' )
            ->validator( 'Validate::email' ),
        Field::inst( 'agent.mobile' )
            ->validator( 'Validate::notEmpty' )
            ->validator( 'Validate::numeric' )
            ->validator( function ( $val, $data, $opts ) 
                {   
                if  (strlen( $val ) < 7)  
                    {
                    return 'Telephone Number too short';
                    }                           
                else
                    {
                    /*  international prefix present?  yes so there is a 15 digit limit */  
                    if  ((substr($val,0,2)) <> "00") 
                        {
                            if  (strlen( $val ) > 11) 
                                {
                                    return 'National Telephone Number too long';
                                }
                            else
                                {
                                    return true;                        
                                }
                        }
                    else
                        {   
                        /*  no internation prefix present - so there is a 11 digit limit */
                        if  (strlen( $val ) > 15) 
                            {
                                return 'International Telephone Number too long';
                            }
                        else
                            {
                                return true;                        
                            }       
                        }
                    }
                }),
                
(other fields)  

I could have also validate the country code against an array but have kept this simpler by not doing so. Also this can change over time ad would require updating. Additionally the actual maximum number of digits depends on region codes which again I have not checked for. The resultant complete code could be very long and I am not sure ultimately worth the extra effort of maintaining the complex code. This will at least reduce the number of typing errors.

Also, it should be possible to use the "render" function to display an international telephone number in the format

"00-44-7816514152" which would look nicer on reports. Please add to this discussion if you have a suggestion.

Note there is a fully functional international telephone number plug-in available on the Jquery website - but this plugin insists that the user selects a country by a flag and always uses the full international format. The user may or may not wish to do this and may or may not wish to put in the 00 and country codes either for numbers inside their country so this is not always the best option.

I know the email validation is not completely foolproof either as the domains ae many and varied and will increase as time goes by. It is a basic check of format as is the above intended to be.

Perhaps this could be provided as a "built-in" validator Allan?

Replies

  • allanallan Posts: 61,895Questions: 1Answers: 10,145 Site admin

    Awesome!

    I don't plan to include this functionality built in, but the API is designed to be extensible so additional validators such as this can be easily added.

    Thanks for sharing it with us!

    Regards,
    Allan

  • Dirk FincleyDirk Fincley Posts: 38Questions: 3Answers: 0

    I should have used:-

    " if ((substr($val,0,2)) == "00")" and inverted the if/else clauses to improve readability. "==" being the PHP speak for "equals".

  • Dirk FincleyDirk Fincley Posts: 38Questions: 3Answers: 0
    edited March 2016

    Realised that a "+" and "-" prefix is permitted by the "numeric" validator. I did not handle this so here is an ehanced validator. Obviously any number which begins with a "+" should be considered international.

    Editor::inst( $db, 'agent', 'id' )
        ->fields(
            Field::inst( 'agent.id' )
                ->validator( 'Validate::notEmpty' ),
            Field::inst( 'agent.first_name' )
                ->validator( 'Validate::notEmpty' ),
            Field::inst( 'agent.surname' )
                ->validator( 'Validate::notEmpty' ),
            Field::inst( 'agent.email' )
                ->validator( 'Validate::notEmpty' )
                ->validator( 'Validate::email' ),
            Field::inst( 'agent.mobile' )
                ->validator( 'Validate::notEmpty' )
                ->validator( 'Validate::numeric' )
                ->validator( function ( $val, $data, $opts ) 
                    {   
                    if  ((strlen( $val ) < 7) or ((substr($val,0,1)) =="-") )
                        {
                        return 'Telephone Number too short or contains a minus sign prefix';
                        }                           
                    else
                        {               
                        /*  international prefix ("00" or "+") present - so there is either a 14 or 15 digit limit */   
                        if  (((substr($val,0,2)) == "00")  or ((substr($val,0,1)) =="+") )
                        {   
    
                            if  ((strlen( $val ) > 15) and (substr($val,0,2)== "00"))
                                {
                                    return 'International Telephone Number too long';
                                }
                            else
                                if  ((strlen( $val ) > 14) and (substr($val,0,1)) == "+")
                                {
                                    return 'International Telephone Number too long';
                                }
                                else
                                {
                                    return true;                        
                                }       
                            }
                        else
                        /*  National number - so there is a 11 digit limit */
                            {
                                if  (strlen( $val ) > 11) 
                                    {
                                        return 'National Telephone Number too long';
                                    }
                                else
                                    {
                                        return true;                        
                                    }
                            }
                        }
                    }),
    other fields..
    
    

    This works better and the +44 is a more common representation of an international telephone number anyway so it works well as you can store these on your database using the above validation.

    Seems to work well. Please tell me anyone who sees a problem with it.

This discussion has been closed.