Jump to content

Phone Validation - Not Validating


helenaqurfer
Go to solution Solved by Psycho,

Recommended Posts

I'm trying to create a field that will validation US phone numbers, and afterwards I will be attempting a field to validate income.  So far, for the phone numbers, I have implemented the following regex expression and PHP.  The regex has worked in someone elses implementation, however when I utilize it in this implementation it always returns an error that the phone number isn't valid.  I'm having a difficult time seeing where the difficulty is:

	    //1. Add a new form element...
    add_action('register_form','myplugin_register_form2');
    function myplugin_register_form2 (){
        $phone_number = ( isset( $_POST['phone_number'] ) ) ? $_POST['phone_number']: '';
        ?>
        <p id="phone_number">
            <label for="phone_number"><?php _e('Phone Number <font size="1">(XXX XXX XXXX)</font>','mydomain') ?><br />
                <input type="text" name="phone_number" id="phone_number" class="input" size="25" style="text-align:right" maxlength="14" />
        </p>
        <?php
    }

    //2. Add validation. In this case, we make sure phone_number is required.
    add_filter('registration_errors', 'myplugin_registration_errors2', 10, 3);
    function myplugin_registration_errors2 ($errors, $sanitized_user_login, $user_email) {
    $sPattern = "/^
        (?:                                 # Area Code
            (?:                            
                \(                          # Open Parentheses
                (?=\d{3}\))                 # Lookahead.  Only if we have 3 digits and a closing parentheses
            )?
            (\d{3})                         # 3 Digit area code
            (?:
                (?<=\(\d{3})                # Closing Parentheses.  Lookbehind.
                \)                          # Only if we have an open parentheses and 3 digits
            )?
            [\s.\/-]?                       # Optional Space Delimeter
        )?
        (\d{3})                             # 3 Digits
        [\s\.\/-]?                          # Optional Space Delimeter
        (\d{4})\s?                          # 4 Digits and an Optional following Space
        (?:                                 # Extension
            (?:                             # Lets look for some variation of 'extension'
                (?:
                    (?:e|x|ex|ext)\.?       # First, abbreviations, with an optional following period
                |
                    extension               # Now just the whole word
                )
                \s?                         # Optionsal Following Space
            )
            (?=\d+)                         # This is the Lookahead.  Only accept that previous section IF it's followed by some digits.
            (\d+)                           # Now grab the actual digits (the lookahead doesn't grab them)
        )?                                  # The Extension is Optional
        $/x";                               // /x modifier allows the expanded and commented regex

    $aNumbers = array(
        '123-456-7890x123',
        '123.456.7890x123',
        '123 456 7890 x123',
        '(123) 456-7890 x123',
        '123.456.7890x.123',
        '123.456.7890 ext. 123',
        '123.456.7890 extension 123456',
        '123 456 7890', 
        '123-456-7890ex123',
        '123.456.7890 ex123',
        '123 456 7890 ext123',
        '456-7890',
        '456 7890',
        '456 7890 x123',
        '1234567890',
        '() 456 7890'
    );

    foreach($aNumbers as $sNumber) {
        if (!preg_match($sPattern, $phone_number, $aMatches)) {
          $errors->add( 'phone_number_error', __('<strong>ERROR</strong>: You must include a valid phone number.','mydomain') );

        return $errors;
    }
	}


        if ( empty( $_POST['phone_number'] ) )
            $errors->add( 'phone_number_error', __('<strong>ERROR</strong>: You must include a valid phone number.','mydomain') );

        return $errors;
    }

    //3. Finally, save our extra registration user meta.
    add_action('user_register', 'myplugin_user_register2');
    function myplugin_user_register2 ($user_id) {
        if ( isset( $_POST['phone_number'] ) )
            update_user_meta($user_id, 'phone_number', $_POST['phone_number']);
    }
Link to comment
Share on other sites

Thank you.  I noticed about the variables and also noticed that I didn't want to match against the array but the user input into the field.  I changed it thusly but even if I type a correct format that seems to match the expression I am still getting an invalid number:

    //2. Add validation. In this case, we make sure phone_number is required.
    add_filter('registration_errors', 'myplugin_registration_errors2', 10, 3);
    function myplugin_registration_errors2 ($errors, $sanitized_user_login, $user_email) {
    $sPattern = "/^
        (?:                                 # Area Code
            (?:                            
                \(                          # Open Parentheses
                (?=\d{3}\))                 # Lookahead.  Only if we have 3 digits and a closing parentheses
            )?
            (\d{3})                         # 3 Digit area code
            (?:
                (?<=\(\d{3})                # Closing Parentheses.  Lookbehind.
                \)                          # Only if we have an open parentheses and 3 digits
            )?
            [\s.\/-]?                       # Optional Space Delimeter
        )?
        (\d{3})                             # 3 Digits
        [\s\.\/-]?                          # Optional Space Delimeter
        (\d{4})\s?                          # 4 Digits and an Optional following Space
        (?:                                 # Extension
            (?:                             # Lets look for some variation of 'extension'
                (?:
                    (?:e|x|ex|ext)\.?       # First, abbreviations, with an optional following period
                |
                    extension               # Now just the whole word
                )
                \s?                         # Optionsal Following Space
            )
            (?=\d+)                         # This is the Lookahead.  Only accept that previous section IF it's followed by some digits.
            (\d+)                           # Now grab the actual digits (the lookahead doesn't grab them)
        )?                                  # The Extension is Optional
        $/x";                              

        if (!preg_match($sPattern, $phone_number, $aMatches)) {
          $errors->add( 'phone_number_error', __('<strong>ERROR</strong>: You must include a valid phone number.','mydomain') );
        return $errors;
    }

        if ( empty( $_POST['phone_number'] ) )
            $errors->add( 'phone_number_error', __('<strong>ERROR</strong>: You must include a valid phone number.','mydomain') );
        return $errors;
    }

    //3. Finally, save our extra registration user meta.
    add_action('user_register', 'myplugin_user_register2');
    function myplugin_user_register2 ($user_id) {
        if ( isset( $_POST['phone_number'] ) )
            update_user_meta($user_id, 'phone_number', $_POST['phone_number']);
    }

Check the variables you've used in the foreach loop, and you should see the problem.

Also, you have one invalid phone number in there. Namely the last one, so even if you fix the bug it will still provide you with the error message.

Link to comment
Share on other sites

Above the code previously posted is the field where the user inputs the phone number:

	    //1. Add a new form element...
    add_action('register_form','myplugin_register_form2');
    function myplugin_register_form2 (){
        $phone_number = ( isset( $_POST['phone_number'] ) ) ? $_POST['phone_number']: '';
        ?>
        <p id="phone_number">
            <label for="phone_number"><?php _e('Phone Number <font size="1">(XXX XXX XXXX)</font>','mydomain') ?><br />
                <input type="text" name="phone_number" id="phone_number" class="input" size="25" style="text-align:right" maxlength="14" />
        </p>
        <?php
    }

My impression is it should be pulling this value from what the user enters and then match that against the expression and generate the error if the number does not match the expression.

Edited by helenaqurfer
Link to comment
Share on other sites

I have done a lot of validations with respect to phones, names, addresses, etc. Are you really concerned about the format of the phone number entered, or are you really wanting to know that the value they have entered is valid as a phone number? A user may enter a phone number in many different formats, but could still be a "valid" number:

 

123-456-7890

(123) 456-7890

123.456.7890

123 456 7890

etc. etc.

 

It would be a waste of time trying to build logic to validate on any possible way a human might enter he phone number. Unless you have a specific business requirement to verify the format of the value entered, just verify that the digits entered would make a valid number. Then you can strip-out all non-numeric characters and store that. Then, when you display the phone numbers you can format them in a consistent way for your application.

 

So the logic could be a s simple as:

1. Remove all non-numeric characters

2. Test the length of the remaining characters

Edited by Psycho
Link to comment
Share on other sites

Hi Psycho, it's more of a formatting issue.  I'm not as concerned about users entering fake numbers - it's more about apprising them if they have accidentally missed a digit, typed a letter, etc...as a courtesy and a validation that they have entered their actual number and have not made any mistakes.

 

So what you are suggesting is to strip all non-numerical characters and then just test for length?

Link to comment
Share on other sites

  • Solution

Hi Psycho, it's more of a formatting issue.  I'm not as concerned about users entering fake numbers - it's more about apprising them if they have accidentally missed a digit, typed a letter, etc...as a courtesy and a validation that they have entered their actual number and have not made any mistakes.

 

So what you are suggesting is to strip all non-numerical characters and then just test for length?

 

No, it's NOT a formatting issue if you are wanting to verify that the value entered may have been missing a digit. That is my whole point. Trying to validate the value as a "formatted" phone number is a waste of time unless you are restricting the user to a specific format for a particular business reason. You are wanting to validate that the value is valid for use as a phone number (verifying that it is an actual phone number is near impossible). So, what do you care if the user enters in "123-456-7890" or "123.456.7890" or any other format with those same 10 digits?

 

Here is an example function that will return false if the value doesn't contain exactly 10 digits, otherwise it just returns the 10 digits with no other characters. You would then store just the 10 digits in the database. Then whenever you need to display the phone numbers on your site, create a formatting function that will display all the phone numbers consistently. It would look unprofessional if all the phone numbers were displayed differently based upon the user who entered them..

 

function valid_phone($phone)
{
    $phone = preg_replace('#[^\d]#', '', $phone);
    if(strlen($phone) != 10) { return false; }
    return $phone;
}
Link to comment
Share on other sites

JavaScript would like to differ ;P

Not really, JS has the same rule. The difference is in JS variables defined outside of a function, exist within it. Not that it really matters in a thread about PHP.

 

function x(){
  var y=100;
}

x();
console.log(y); //y does not exist here.
Link to comment
Share on other sites

No, it doesn't matter, but since this thread has been marked as solved, I though that I could throw in a joke.

 

JS allows a function to define a global variable by omitting the var keyword, though, similar to PHP globals.

Link to comment
Share on other sites

JS allows a function to define a global variable by omitting the var keyword, though, similar to PHP globals.

Not really, what happens is you end up creating a property on the global object, which is different from variables technically. It "works" but is poor practice and frowned upon (like globals in php).

 

var somevar = 'blah';
console.log(window.somevar) //undefined because somevar is a variable, not a property
function x(){
  somevar = 'blah';
}
x();
console.log(window.somevar); //'blah' because somevar was created as a property.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.