phone.int.inc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. function phone_int_metadata() {
  3. // These strings are translated using t() on output.
  4. return array(
  5. 'error' => '"%value" is not a valid Italian phone number<br>Italian phone numbers should only ...',
  6. );
  7. }
  8. /**
  9. * Verifies that $phonenumber is a valid international phone number as per ITU or,
  10. * if a default country code is specified, a valid subscriber number.
  11. *
  12. * @see http://www.itu.int/rec/T-REC-E.123/en
  13. *
  14. * @param $phonenumber
  15. * International phone number to validate
  16. * @return
  17. * TRUE if valid, FALSE if otherwise.
  18. */
  19. function valid_int_phone_number($phonenumber) {
  20. $phonenumber = trim($phonenumber);
  21. if ($phonenumber === '') {
  22. return FALSE;
  23. }
  24. $phonenumber = _normalize_country_code($phonenumber);
  25. $base_phonenumber = str_replace(array('.', '(', ')', '[', ']', '-', '+', ' '), '', $phonenumber);
  26. if (!isset($field['phone_int_max_length'])) {
  27. $field['phone_int_max_length'] = 15;
  28. }
  29. if (strlen($base_phonenumber) > $field['phone_int_max_length']) {
  30. $error = t('Invalid international phone number: Phone number is too long; international phone numbers are limited to 15 digits.');
  31. return FALSE;
  32. }
  33. // Check if digits are used in the base_phonenumber
  34. if (!ctype_digit($base_phonenumber)) {
  35. $error = t('Invalid international phone number: Phone number contains invalid characters; only allowed characters are numbers and punctuation.');
  36. return FALSE;
  37. }
  38. // Extract country code and see if it's correct:
  39. preg_match('/^\+(\d+)/', $phonenumber, $matches);
  40. $cc = $matches[1];
  41. if (strlen($cc) > 3) {
  42. $error = array(
  43. t('Invalid international phone number: Country code "+%cc" is too long; valid country codes are three digits or less.'),
  44. array('%cc' => $cc)
  45. );
  46. return FALSE;
  47. }
  48. //drupal_set_message('langue cc = ' . $cc, 'error');
  49. // TODO: Check if parentheses/brackets add up.
  50. // TODO: Validate the number against the country rules.
  51. // For now, validate only against a limited number of countries.
  52. $countrycode = phone_country_code_convert($cc);
  53. //drupal_set_message('langue countrycode = ' . $countrycode, 'error');
  54. if (!empty($countrycode)) {
  55. $valid_phone_function = 'valid_'. $countrycode . '_phone_number';
  56. module_load_include('inc', 'phone', 'phone.'. $countrycode);
  57. if (function_exists($valid_phone_function)) {
  58. return $valid_phone_function($phonenumber, $field);
  59. }
  60. else {
  61. return TRUE;
  62. }
  63. }
  64. return FALSE;
  65. }
  66. /**
  67. * Formats $phonenumber into the standard representation of international
  68. * numbers as per E.123.
  69. *
  70. * @param $phonenumber
  71. * International phone number to format
  72. * @return
  73. * Formatted international phone number
  74. */
  75. function format_int_phone_number($phonenumber, $field = array()) {
  76. $phonenumber = trim($phonenumber);
  77. if ($phonenumber === '') {
  78. return '';
  79. }
  80. $phonenumber = _normalize_country_code($phonenumber, $field);
  81. $bits = preg_split('/[.()\[\]\- ]/', $phonenumber, -1, PREG_SPLIT_NO_EMPTY);
  82. // $bits[0] is the country code WITH a plus sign.
  83. if (isset($bits[1])) {
  84. // This is the first non-CC segment, so it could have the NDN.
  85. switch ($bits[1][0]) {
  86. case 0:
  87. $bits[1] = substr($bits[1], 1);
  88. break;
  89. }
  90. switch ($bits[1]) {
  91. case 0:
  92. case 7:
  93. case 8:
  94. array_splice($bits, 1, 1);
  95. break;
  96. }
  97. }
  98. return implode(' ', $bits);
  99. }
  100. /**
  101. * Adds a country code to a phone number if necessary.
  102. *
  103. * @param $phonenumber
  104. * International or local phone number to format
  105. * @return
  106. * International phone number with country code
  107. */
  108. function _normalize_country_code($phonenumber, $field = array()) {
  109. if ($phonenumber[0] !== '+') {
  110. $cc = isset($field['phone_default_country_code']) ? $field['phone_default_country_code'] : '1';
  111. return "+$cc $phonenumber";
  112. }
  113. return $phonenumber;
  114. }
  115. /**
  116. * Returns the country code in the desired format.
  117. *
  118. * @todo Fill in the rest of the country code values.
  119. *
  120. * @param $code
  121. * Country code to convert (either numeric or 2-letter abbreviation)
  122. * @param $input_type
  123. * Type of country code to convert (either numeric or 2-letter abbreviation)
  124. * @return
  125. * Converted country code
  126. */
  127. function phone_country_code_convert($code, $input_type = 'digits') {
  128. static $codes;
  129. if (!$codes) {
  130. $codes = array(
  131. '1' => 'ca',
  132. '1' => 'us',
  133. '7' => 'ru',
  134. '20' => 'eg',
  135. '27' => 'za',
  136. '30' => 'gr',
  137. '31' => 'nl',
  138. '32' => 'be',
  139. '33' => 'fr',
  140. '34' => 'es',
  141. '36' => 'hu',
  142. '39' => 'it',
  143. '39' => 'va',
  144. '40' => 'ro',
  145. '41' => 'ch',
  146. '43' => 'at',
  147. '44' => 'gb',
  148. '45' => 'dk',
  149. '46' => 'se',
  150. '47' => 'no',
  151. '48' => 'pl',
  152. '49' => 'de',
  153. '51' => 'pe',
  154. '52' => 'mx',
  155. '53' => 'cu',
  156. '54' => 'ar',
  157. '55' => 'br',
  158. '56' => 'cl',
  159. '57' => 'co',
  160. '58' => 've',
  161. '60' => 'my',
  162. '61' => 'au',
  163. '61' => 'cc',
  164. '61' => 'cx',
  165. '62' => 'id',
  166. '63' => 'ph',
  167. '64' => 'nz',
  168. '65' => 'sg',
  169. '66' => 'th',
  170. '81' => 'jp',
  171. '82' => 'kr',
  172. '84' => 'vn',
  173. '86' => 'cn',
  174. '90' => 'tr',
  175. '91' => 'in',
  176. '92' => 'pk',
  177. '93' => 'af',
  178. '94' => 'lk',
  179. '95' => 'mm',
  180. '98' => 'ir',
  181. '212' => 'ma',
  182. '213' => 'dz',
  183. '216' => 'tn',
  184. '218' => 'ly',
  185. '220' => 'gm',
  186. '221' => 'sn',
  187. '222' => 'mr',
  188. '223' => 'ml',
  189. '224' => 'gn',
  190. '225' => 'ci',
  191. '226' => 'bf',
  192. '227' => 'ne',
  193. '228' => 'tg',
  194. '229' => 'bj',
  195. '230' => 'mu',
  196. '231' => 'lr',
  197. '232' => 'sl',
  198. '233' => 'gh',
  199. '234' => 'ng',
  200. '235' => 'td',
  201. '236' => 'cf',
  202. '237' => 'cm',
  203. '238' => 'cv',
  204. '239' => 'st',
  205. '240' => 'gq',
  206. '241' => 'ga',
  207. '242' => 'cg',
  208. '243' => 'cd',
  209. '244' => 'ao',
  210. '245' => 'gw',
  211. '246' => 'io',
  212. '248' => 'sc',
  213. '249' => 'sd',
  214. '250' => 'rw',
  215. '251' => 'et',
  216. '252' => 'so',
  217. '253' => 'dj',
  218. '254' => 'ke',
  219. '255' => 'tz',
  220. '256' => 'ug',
  221. '257' => 'bi',
  222. '258' => 'mz',
  223. '260' => 'zm',
  224. '261' => 'mg',
  225. '263' => 'zw',
  226. '264' => 'na',
  227. '265' => 'mw',
  228. '266' => 'ls',
  229. '267' => 'bw',
  230. '268' => 'sz',
  231. '269' => 'km',
  232. '269' => 'yt',
  233. '290' => 'sh',
  234. '291' => 'er',
  235. '297' => 'aw',
  236. '298' => 'fo',
  237. '299' => 'gl',
  238. '350' => 'gi',
  239. '351' => 'pt',
  240. '352' => 'lu',
  241. '353' => 'ie',
  242. '354' => 'is',
  243. '355' => 'al',
  244. '356' => 'mt',
  245. '357' => 'cy',
  246. '358' => 'fi',
  247. '359' => 'bg',
  248. '370' => 'lt',
  249. '371' => 'lv',
  250. '372' => 'ee',
  251. '373' => 'md',
  252. '374' => 'am',
  253. '375' => 'by',
  254. '376' => 'ad',
  255. '377' => 'mc',
  256. '378' => 'sm',
  257. '380' => 'ua',
  258. '381' => 'rs',
  259. '382' => 'me',
  260. '385' => 'hr',
  261. '386' => 'si',
  262. '387' => 'ba',
  263. '389' => 'mk',
  264. '420' => 'cz',
  265. '421' => 'sk',
  266. '423' => 'li',
  267. '500' => 'fk',
  268. '501' => 'bz',
  269. '502' => 'gt',
  270. '503' => 'sv',
  271. '504' => 'hn',
  272. '505' => 'ni',
  273. '506' => 'cr',
  274. '507' => 'pa',
  275. '508' => 'pm',
  276. '509' => 'ht',
  277. '590' => 'gp',
  278. '591' => 'bo',
  279. '592' => 'gy',
  280. '593' => 'ec',
  281. '594' => 'gf',
  282. '595' => 'py',
  283. '596' => 'mq',
  284. '597' => 'sr',
  285. '598' => 'uy',
  286. '599' => 'an',
  287. '670' => 'tp',
  288. '672' => 'nf',
  289. '673' => 'bn',
  290. '674' => 'nr',
  291. '675' => 'pg',
  292. '676' => 'to',
  293. '677' => 'sb',
  294. '678' => 'vu',
  295. '679' => 'fj',
  296. '680' => 'pw',
  297. '681' => 'wf',
  298. '682' => 'ck',
  299. '683' => 'nu',
  300. '686' => 'ki',
  301. '687' => 'nc',
  302. '688' => 'tv',
  303. '689' => 'pf',
  304. '690' => 'tk',
  305. '691' => 'fm',
  306. '692' => 'mh',
  307. '850' => 'kp',
  308. '852' => 'hk',
  309. '853' => 'mo',
  310. '855' => 'kh',
  311. '856' => 'la',
  312. '880' => 'bd',
  313. '886' => 'tw',
  314. '960' => 'mv',
  315. '961' => 'lb',
  316. '962' => 'jo',
  317. '963' => 'sy',
  318. '964' => 'iq',
  319. '965' => 'kw',
  320. '966' => 'sa',
  321. '967' => 'ye',
  322. '968' => 'om',
  323. '970' => 'ps',
  324. '971' => 'ae',
  325. '972' => 'il',
  326. '973' => 'bh',
  327. '974' => 'qa',
  328. '975' => 'bt',
  329. '976' => 'mn',
  330. '977' => 'np',
  331. '992' => 'tj',
  332. '993' => 'tm',
  333. '994' => 'az',
  334. '995' => 'ge',
  335. '996' => 'kg',
  336. '998' => 'uz',
  337. );
  338. }
  339. if ($input_type == 'alpha') {
  340. $codes = array_flip($codes);
  341. }
  342. return isset($codes[$code]) ? $codes[$code] : FALSE;
  343. }