My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php
/**
* PHONES CLASS
*
* @package Phones
* @author $Author$
* @version $Rev$
* @lastrevision $Date$
* @filesource $URL$
* @license $License: http://creativecommons.org/licenses/by-sa/3.0/$
* @copyright $Copyright: (c)2010 Chuck Burgess. All Rights Reserved.$
*
* Please feel free to visit my blog http://blogchuck.com
*
* Description of Class, usage, and documentation can be found on the wiki:
* http://code.google.com/p/blogchuck/wiki/PhonesClass
*
*/
class Phones
{
// optional country code (will always be 1)
private $us_cc_regex = '(?:1)?';

// base
private $npa = '[2-9][0-8][0-9]';
private $nxx = '[2-9][0-9]{2}';
private $xxxx = '[0-9]{4}';

// inalid area_codes
private $invalid_npa = '37[0-9]|96[0-9]|[2-9]11'; // 37x & 96x set aside : x11 not used as area codes
private $invalid_nxx = '[2-9]11'; // x11 not used as NXX codes either

// invalid phone numbers
private $invalid_nxx_xxxx = '555(01([0-9][0-9])|1212)';

# FILTERS #
// filtered area_codes ($npa IS this number)
private $toll_free = '8(00|22|33|44|55|66|77|80|81|82|88)'; // valid toll free area code designations
private $special = '[2-9](00|11|22|33|44|55|66|77|88|99)'; // known as ERCs, designated as special services (duplicates the 8 x11 codes)

#subsets of special
private $toll = '900';
private $service = '500';
private $carrier = '700';


/**
* Filters
*
* This will append the regex to filter phone numbers based on business rules.
*
*/
function _buildFilter($filter)
{
switch (strtolower($filter)) {
case 'toll_free':
$filter_regex = '|'.$this->toll_free;
break;
case 'toll':
$filter_regex = '|'.$this->toll;
break;
case 'toll_all':
$filter_regex = '|'.$this->toll_free.'|'.$this->toll;
break;
case 'service':
$filter_regex = '|'.$this->service;
break;
case 'carrier':
$filter_regex = '|'.$this->carrier;
break;
case 'special':
$filter_regex = '|'.$this->special;
break;
case 'all':
$filter_regex = '|'.$this->toll_free.'|'.$this->special;
break;
default:
break;
}
return $filter_regex;
}


/**
* Clean the phone number for verification
*
* Basic rules of the phone number will eliminate the invalid data:
* √ - phone numbers contain numbers only (no letters, puncuation, etc.)
* √ - phone numbers may include extensions (which need to be detached)
*
*/
function cleansePhone($phone)
{
// split the phone on x. if there is an extension, the string will most likely always have an x
list($phone, $ext) = split('x', $phone);

// remove anything that is not a digit from the phone number
$phone = preg_replace('/\D/', '', $phone);

// remove anything that is not a digit from the extension
$ext = preg_replace('/\D/', '', $ext);

// return the cleansed numbers
return array($phone, $ext);
}

/**
* Validation Rules: (http://www.nanpa.com/area_codes/)
* Reference Information
* - http://en.wikipedia.org/wiki/North_American_Numbering_Plan#List_of_NANPA_countries_and_territories
*
* NPA (Area) Codes (NXX)
* √ - N is any digit 2 thru 9 (area code cannot start with a 1)
* √ - N11 service codes not used as area codes (i.e. 911, 811, 711)
* √ - N9X expansion codes cannot be used (known as expansion codes)
* √ - 37X & 96X cannot be used (set aside for unanticipated purposes)
*
* Central Office Codes (exchanges, prefixes, or simply NXXs)
* √ - N cannot be 0 or 1
*
* Carrier Identification Codes (CIC) XXXX
* √ - X is any digit 0-9
*
* Phone Number
* √ - phone number cannot be 555-0100 thru 555-0199 (fictional numbers)
* √ - phone number 555-1212 is for information (not assignable)
*
* Filters
* There are a base set of filter that can be applied during the validation process.
* - TOLL_FREE
* - SPECIAL
* - TOLL
* - SERVICE
* - CARRIER
* - ALL
*
* TODO:
* Add filters for:
* - NPA country (US|CANADA)
* - NPA state/province
* - custom filtering
*/
function validatePhone($phone, $filter = null)
{

// check to see if there is a filter
if(isset($filter)){
$filter_regex = '';
// check to see if the filter is an array
if(is_array($filter)){
// concantenate each filter
foreach($filter as $name){
$filter_regex .= $this->_buildFilter($name);
}
}else{
$filter_regex = $this->_buildFilter($filter);
}
}

list($phone, $ext) = $this->cleansePhone($phone);

// basic regex to confirm the phone number is one that can be called
$regex = '/^'.$this->us_cc_regex.'(?(?!('.$this->invalid_npa.$filter_regex.'))'.$this->npa.')(?(?!('.$this->invalid_nxx.'))'.$this->nxx.$this->xxxx.')(?<!('.$this->invalid_nxx_xxxx.'))'.'$/';

// return valid phone with ext otherwise, false
if(preg_match($regex, $phone))
{
return array($phone, $ext);
} else {
return false;
}

}


/**
* Format the phone
*
* $phone : the phone number (could come in as 10 or 11 digits)
* $delimiter : what to use as delimiters in the phone (defaults to dash)
* $format : will determine what get's sent back
* {default} : formats what ever number is passed resulting in optional 1
* 10d : removes the 1 from the front and returns only xxx-xxx-xxxx
* 1+10d : will add the 1 if it is not there returning 1-xxx-xxx-xxxx
*
* Return the phone number in a standard format after it has been cleansed, validated, and verified
* 10d XXX-XXX-XXXX
* 1+10d 1-XXX-XXX-XXXX
*
* TODO:
* - allow (NPA)-XXX-XXX formatted phone numbers
*/
function formatPhone($phone, $delimiter = '-', $country_code = false)
{
list($phone, $ext) = $this->cleansePhone($phone);

if($country_code){
$phone = preg_replace('/^(1?)([0-9]{3})([0-9]{3})([0-9]{4})$/', "1$delimiter$2$delimiter$3$delimiter$4", $phone);
}else{
$phone = preg_replace('/^(1?)([0-9]{3})([0-9]{3})([0-9]{4})$/', "$2$delimiter$3$delimiter$4", $phone);
}

// return the formated phone and extension
return array($phone, $ext);
}

}
?>

Change log

r32 by cdburgess on Jan 23, 2010   Diff
Fixes the regex filter. Was not catching
ERCs for NXX. Also modified the classes so
that they return the phone number and
extension. I also modified the
validatePhone and formatPhone to cleanse
the phone number prior to running the
function on the phone number.
Go to: 
Project members, sign in to write a code review

Older revisions

r12 by cdburgess on Jan 19, 2010   Diff
Updated header to work with propset on
SVN.
r11 by cdburgess on Jan 19, 2010   Diff
Updated header to work with propset on
SVN.
r10 by cdburgess on Jan 19, 2010   Diff
Updated header to work with propset on
SVN.
All revisions of this file

File info

Size: 6025 bytes, 208 lines

File properties

License
http://creativecommons.org/licenses/b...-sa/3.0/
Copyright
(c)2010 Chuck Burgess. All rights reserved.
svn:keywords
Date Author Id Copyright Revision License URL
Powered by Google Project Hosting