Skip to content

Instantly share code, notes, and snippets.

@mymizan
Created May 10, 2013 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mymizan/5551946 to your computer and use it in GitHub Desktop.
Save mymizan/5551946 to your computer and use it in GitHub Desktop.
Phone number formatting and normalization class taken from OpenVBX project
<?php
/**
* "The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* The Original Code is OpenVBX, released June 15, 2010.
* The Initial Developer of the Original Code is Twilio Inc.
* Portions created by Twilio Inc. are Copyright (C) 2010.
* All Rights Reserved.
* Contributor(s):
**/
class PhoneNumberException extends Exception {}
class PhoneNumber
{
const TYPE_DOMESTIC = 1;
const TYPE_INTERNATIONAL = 2;
const TYPE_PREMIUM = 3;
const TYPE_UNKNOWN = 4;
const TYPE_TOLLFREE = 5;
const TYPE_DOMESTIC_INVALID = 6;
public function validatePhoneNumber($number) {
// get type
$normalized = self::normalizePhoneNumberToE164($number); // analyze will alter the number to a normalized form
switch($type = self::analyzePhoneNumber($normalized)) {
case self::TYPE_DOMESTIC:
case self::TYPE_TOLLFREE:
case self::TYPE_INTERNATIONAL:
return $type;
default:
throw new PhoneNumberException("Number is not a US, Canadian or toll free phone number");
break;
}
}
public static function convertAlphaNumeric($phone) {
// conver letters to numbers
return str_ireplace(array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'), array('2','2','2','3','3','3','4','4','4','5','5','5','6','6','6','7','7','7','7','8','8','8','9','9','9','9'), $phone);
}
public static function normalizePhoneNumberToE164($phone) {
// convert letters to numbers
$phone = self::convertAlphaNumeric($phone);
// get rid of any non (digit, + character)
$phone = preg_replace('/[^0-9+]/', '', $phone);
// validate intl 10
if(preg_match('/^\+([2-9][0-9]{9})$/', $phone, $matches)){
return "+{$matches[1]}";
}
// validate US DID
if(preg_match('/^\+?1?([2-9][0-9]{9})$/', $phone, $matches)){
return "+1{$matches[1]}";
}
// validate INTL DID
if(preg_match('/^\+?([2-9][0-9]{8,14})$/', $phone, $matches)){
return "+{$matches[1]}";
}
// premium US DID
if(preg_match('/^\+?1?([2-9]11)$/', $phone, $matches)){
return "+1{$matches[1]}";
}
return false;
}
public static function analyzePhoneNumber($phone) {
// normalize for letters
$phone = self::normalizePhoneNumberToE164($phone);
if(self::isShortPremium($phone)) {
return self::TYPE_PREMIUM;
}
// if it's a north american number
if(self::isNorthAmericanDID($phone)) {
// check that it's not premium
if(self::isNorthAmericanPremiumDID($phone))
return self::TYPE_PREMIUM;
// check if it's toll free
if(preg_match('/^\+?1?(8([0-9])\2)|(88[0-9])[0-9]{7}$/', $phone))
return self::TYPE_TOLLFREE;
return self::TYPE_DOMESTIC;
}
// wasn't north american, check for international
if($tmp = self::isInternationalDID($phone)) {
return self::TYPE_INTERNATIONAL;
}
// unkonwn type
return self::TYPE_UNKNOWN;
}
public static function isNorthAmericanDID($phone) {
// get rid of any non (digit, + character)
$phone = preg_replace('/[^0-9+]/', '', $phone);
// validate North American DID
if(preg_match('/^\+1([2-9][0-9]{9})$/', $phone, $matches))
return true;
return false;
}
public static function isShortPremium($phone) {
// emergency and info services
if(preg_match('/^\+?1?([0-9]11)$/', $phone, $matches))
return true;
return false;
}
public static function isNorthAmericanPremiumDID($phone) {
// get rid of any non (digit, + character)
$phone = preg_replace('/[^0-9+]/', '', $phone);
// validate North American Premium DID (toll services)
if(preg_match('/^\+?1?(((900)|(976))[0-9]{7})$/', $phone, $matches))
return true;
// full dial information services
if(preg_match('/^\+?1?([2-9][0-9]{2}5551212)$/', $phone, $matches))
return true;
return false;
}
public static function isInternationalDID($phone) {
// get rid of any non (digit, + character)
$phone = preg_replace('/[^0-9+]/', '', $phone);
// validate INTL DID
if(preg_match('/^\+?([2-9][0-9]{8,14})$/', $phone, $matches))
return true;
return false;
}
public static function decodeType($type) {
switch($type) {
case self::TYPE_DOMESTIC:
return "Domestic";
break;
case self::TYPE_INTERNATIONAL:
return "International";
break;
case self::TYPE_PREMIUM:
return "Domestic Premium";
break;
case self::TYPE_TOLLFREE:
return "Toll Free";
break;
case self::TYPE_DOMESTIC_INVALID:
return "Domestic Invalid";
break;
default:
return "Unkown";
break;
}
}
public static function normalizeE164ForDisplay($e164Number) {
preg_match("/^\+?1?([2-9][0-9]{8,13})$/",$e164Number,$match);
if(strlen($match[1]))
return $match[1];
else return $e164Number;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment