### Eclipse Workspace Patch 1.0 #P phone Index: phone.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/phone/phone.module,v retrieving revision 1.23 diff -u -r1.23 phone.module --- phone.module 8 Mar 2009 00:04:26 -0000 1.23 +++ phone.module 24 Jun 2009 16:23:54 -0000 @@ -1,12 +1,12 @@ array('label' => t('French Phone Numbers')), - 'it_phone' => array('label' => t('Italian Phone Numbers')), + 'it_phone' => array('label' => t('Italian Phone Numbers')), 'ca_phone' => array('label' => t('US & Canadian Phone Numbers')), - 'cr_phone' => array('label' => t('Costa Rican Phone Numbers')), + 'cr_phone' => array('label' => t('Costa Rican Phone Numbers')), 'uk_phone' => array('label' => t('British (UK) Phone Numbers')), 'ru_phone' => array('label' => t('Russian Phone Numbers')), 'es_phone' => array('label' => t('Spanish Phone Numbers')), 'au_phone' => array('label' => t('Australian Phone Numbers')), - 'cs_phone' => array('label' => t('Czech Phone Numbers')), + 'cs_phone' => array('label' => t('Czech Phone Numbers')), 'hu_phone' => array('label' => t('Hungarian Phone Numbers')), - 'nl_phone' => array('label' => t('Dutch Phone Numbers')) - ); + 'nl_phone' => array('label' => t('Dutch Phone Numbers')), + 'int_phone'=> array('label' => t('International Phone Numbers (ITU)')), + ); } /** @@ -92,10 +93,10 @@ * (see Views Documentation). * When providing several filters, it is recommended to use the 'name' * attribute in order to let the user distinguish between them. If no 'name' - * is specified for a filter, the key of the filter will be used instead. + * is specified for a filter, the key of the filter will be used instead. */ -function phone_field_settings($op, $field) { - switch ($op) { +function phone_field_settings($op, $field) { + switch ($op) { case 'form': $form = array(); $form['phone_country_code'] = array( @@ -115,7 +116,24 @@ '#title' => t('Use parentheses around area code'), '#default_value' => isset($field['ca_phone_parentheses']) ? $field['ca_phone_parentheses'] : 1, ); - } + } + if ($field['type'] == 'int_phone') { + $form['phone_int_help'] = array( + '#type' => 'markup', + '#value' => t('International phone numbers are in the form +XX YYYYYYY where XX is a country code and YYYYYYY is the local number. This field type is based off of the E.123 specification.'), + ); + $form['phone_default_country_code'] = array( + '#type' => 'textfield', + '#title' => t('Default country code to add to international numbers without one (omit + sign)'), + '#default_value' => isset($field['phone_default_country_code']) ? $field['phone_default_country_code'] : '1', + ); + $form['phone_int_max_length'] = array( + '#type' => 'textfield', + '#title' => t('Maximum length of international numbers, according to the ITU this is 15'), + '#default_value' => isset($field['phone_int_max_length']) ? $field['phone_int_max_length'] : '15', + ); + } + return $form; case 'save': @@ -123,25 +141,29 @@ if ($field['type'] == 'ca_phone') { array_push($settings, 'ca_phone_separator', 'ca_phone_parentheses'); } - return $settings; + if ($field['type'] == 'int_phone') { + array_push($settings, 'phone_default_country_code', 'phone_int_max_length'); + } + return $settings; case 'database columns': if ($field['type'] == 'fr_phone' || $field['type'] == 'it_phone' || $field['type'] == 'ca_phone' - || $field['type'] == 'cr_phone' + || $field['type'] == 'cr_phone' || $field['type'] == 'uk_phone' || $field['type'] == 'ru_phone' || $field['type'] == 'es_phone' || $field['type'] == 'au_phone' || $field['type'] == 'cs_phone' - || $field['type'] == 'hu_phone' - || $field['type'] == 'nl_phone' - ) { + || $field['type'] == 'hu_phone' + || $field['type'] == 'nl_phone' + || $field['type'] == 'int_phone' + ) { $columns = array( 'value' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE), ); - } - return $columns; + } + return $columns; } } @@ -178,7 +200,7 @@ * have no return value. * * In most cases, only "validate" operations is relevant ; the rest - * have default implementations in content_field() that usually suffice. + * have default implementations in content_field() that usually suffice. */ function phone_field($op, &$node, $field, &$node_field, $teaser, $page) { switch ($op) { @@ -196,7 +218,7 @@ } if ($field['type'] == 'cr_phone' && !valid_phone_number('cr', $item['value'])) { form_set_error($field['field_name'], t('"%value" is not a valid Costa Rican phone number!
Costa Rican phone numbers should contain only numbers and spaces be like 99 99 99 99 with an optional prefix of "+506" or "00506".', array('%value' => $item['value']))); - } + } if ($field['type'] == 'uk_phone' && !valid_phone_number('uk', $item['value'])) { form_set_error($field['field_name'], t('"%value" is not a valid British phone number
British Phone numbers should .... ', array('%value' => $item['value']))); } @@ -214,10 +236,13 @@ } if ($field['type'] == 'hu_phone' && !valid_phone_number('hu', $item['value'])) { form_set_error($field['field_name'], t('"%value" is not a valid Hungarian phone number!
Hungarian phone numbers should contain only numbers and spaces be like 70 999 9999 with an optional prefix of "+36" or "06".', array('%value' => $item['value']))); - } + } if ($field['type'] == 'nl_phone' && !valid_phone_number('nl', $item['value'])) { form_set_error($field['field_name'], t('"%value" is not a valid Dutch phone number!
Dutch phone numbers should contain only numbers and spaces and - and be like 099-9999999 with an optional prefix of "+31".', array('%value' => $item['value']))); - } + } + if ($field['type'] == 'int_phone' && !valid_phone_number('nl', $item['value'])) { + form_set_error($field['field_name'],t('"%value" is not a valid international phone number
International phone numbers should contain a country code prefixed by a plus sign followed by the local number.', array('%value' => $item['value']))); + } } } break; @@ -237,7 +262,7 @@ } if ($field['type'] == 'cr_phone') { $node_field[$delta]['value'] = format_phone_number('cr', $node_field[$delta]['value'], $field); - } + } if ($field['type'] == 'uk_phone') { $node_field[$delta]['value'] = format_phone_number('uk', $node_field[$delta]['value'], $field); } @@ -255,10 +280,13 @@ } if ($field['type'] == 'hu_phone') { $node_field[$delta]['value'] = format_phone_number('hu', $node_field[$delta]['value'], $field); - } + } if ($field['type'] == 'nl_phone') { $node_field[$delta]['value'] = format_phone_number('nl', $node_field[$delta]['value'], $field); - } + } + if ($field['type'] == 'int_phone') { + $node_field[$delta]['value'] = format_phone_number('int', $node_field[$delta]['value'], $field); + } } } break; @@ -275,7 +303,7 @@ return $phonenumber; } */ - + /** *Implementation of hook_field_formatter_info(). * @@ -342,30 +370,30 @@ * 1 => array( * '#item' => $items[1], * ), - * ), + * ), * ); */ function phone_field_formatter_info() { return array( 'default' => array( 'label' => 'Default', - 'field types' => array('fr_phone', - 'it_phone', - 'ca_phone', - 'cr_phone', - 'uk_phone', + 'field types' => array('fr_phone', + 'it_phone', + 'ca_phone', + 'cr_phone', + 'uk_phone', 'ru_phone', 'es_phone', 'au_phone', - 'cs_phone', + 'cs_phone', 'hu_phone', - 'nl_phone' + 'nl_phone' ), - 'multiple values' => CONTENT_HANDLE_CORE, + 'multiple values' => CONTENT_HANDLE_CORE, ), ); - } - + } + /** * Implementation of hook_field_formatter(). * @@ -402,10 +430,10 @@ else { $text = check_plain($item['value']); } - // iPhone Support + // iPhone Support if (strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') !== FALSE) { $text = '' . $text . ''; - } + } return $text; } @@ -421,28 +449,29 @@ * differently. * * IMPORTANT! - field and widget names will be truncated to 32 characters in - * the database and in internal arrays, like content_fields(). + * the database and in internal arrays, like content_fields(). */ function phone_widget_info() { return array( 'phone_textfield' => array( 'label' => t('Textfield'), - 'field types' => array('fr_phone', - 'it_phone', - 'ca_phone', - 'cr_phone', - 'uk_phone', + 'field types' => array('fr_phone', + 'it_phone', + 'ca_phone', + 'cr_phone', + 'uk_phone', 'ru_phone', 'es_phone', 'au_phone', 'cs_phone', 'hu_phone', - 'nl_phone' + 'nl_phone', + 'int_phone', ), 'multiple values' => CONTENT_HANDLE_CORE, 'callbacks' => array( 'default value' => CONTENT_CALLBACK_DEFAULT, - ), + ), ), ); } @@ -463,14 +492,14 @@ * This varies depending on the operation. * - "form": an array of form elements to add to the settings page. * - "validate": no return value. Use form_set_error(). - * - "save": an array of names of form elements to be saved in the database. + * - "save": an array of names of form elements to be saved in the database. */ function phone_widget_settings($op, $widget) { switch ($op) { case 'form': case 'validate': - break; //do nothing + break; //do nothing case 'save': return array(); @@ -506,7 +535,7 @@ * the order of this item in the array of subelements (0, 1, 2, etc) * * @return - * the form item for a single element for this field + * the form item for a single element for this field */ function phone_widget(&$form, &$form_state, $field, $items, $delta = 0) { $element = array( @@ -624,90 +653,90 @@ } /** - * Verification for Phone Numbers. + * Verification for Phone Numbers. * * @param string $countrycode * @param string $phonenumber - * @return boolean Returns boolean FALSE if the phone number is not valid. + * @return boolean Returns boolean FALSE if the phone number is not valid. */ function valid_phone_number($countrycode, $phonenumber) { - $countrycode = trim($countrycode); + $countrycode = trim($countrycode); $phonenumber = trim($phonenumber); - if ($countrycode == 'fr' - || $countrycode == 'it' + if ($countrycode == 'fr' + || $countrycode == 'it' || $countrycode == 'ca' - || $countrycode == 'cr' + || $countrycode == 'cr' || $countrycode == 'uk' || $countrycode == 'ru' || $countrycode == 'es' || $countrycode == 'au' - || $countrycode == 'cs' - || $countrycode == 'hu' - || $countrycode == 'nl' - ) { - + || $countrycode == 'cs' + || $countrycode == 'hu' + || $countrycode == 'nl' + ) { + //drupal_set_message('langue = ' . $countrycode, 'error'); - $valid_phone_function = 'valid_'. $countrycode . '_phone_number'; + $valid_phone_function = 'valid_'. $countrycode . '_phone_number'; module_load_include('inc', 'phone', 'phone.'. $countrycode); - + if (function_exists($valid_phone_function)) { return $valid_phone_function($phonenumber); } - else { - return FALSE; + else { + return FALSE; } } else { - //Country not taken into account yet - return FALSE; + //Country not taken into account yet + return FALSE; } -} +} /** - * Verification for Phone Numbers. + * Verification for Phone Numbers. * * @param string $countrycode * @param string $phonenumber - * @return boolean Returns boolean FALSE if the phone number is not valid. + * @return boolean Returns boolean FALSE if the phone number is not valid. */ function format_phone_number($countrycode, $phonenumber, $field) { - $countrycode = trim($countrycode); + $countrycode = trim($countrycode); $phonenumber = trim($phonenumber); - if ($countrycode == 'fr' + if ($countrycode == 'fr' || $countrycode == 'it' || $countrycode == 'ca' - || $countrycode == 'cr' + || $countrycode == 'cr' || $countrycode == 'uk' || $countrycode == 'ru' || $countrycode == 'es' || $countrycode == 'au' - || $countrycode == 'cs' - || $countrycode == 'hu' - || $countrycode == 'nl' - ) { - - //drupal_set_message('langue = ' . $countrycode, 'error'); + || $countrycode == 'cs' + || $countrycode == 'hu' + || $countrycode == 'nl' + ) { - $format_phone_function = 'format_'. $countrycode . '_phone_number'; + //drupal_set_message('langue = ' . $countrycode, 'error'); + + $format_phone_function = 'format_'. $countrycode . '_phone_number'; module_load_include('inc', 'phone', 'phone.'. $countrycode); - + if (function_exists($format_phone_function)) { return $format_phone_function($phonenumber, $field); } else { - return FALSE; + return FALSE; } } else { - //Country not taken into account yet - return FALSE; + //Country not taken into account yet + return FALSE; } -} +} /** * Implementation of hook token_list Index: phone.int.inc =================================================================== RCS file: phone.int.inc diff -N phone.int.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ phone.int.inc 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,98 @@ + $field['phone_int_max_length']) { + $error = t('Invalid international phone number: Phone number is too long; international phone numbers are limited to 15 digits.'); + return FALSE; + } + // Check if digits are used + // Remove plus sign: + $digits = substr($base_number, 1); + if (!ctype_digit($digits)) { + $error = t('Invalid international phone number: Phone number contains invalid characters; only allowed characters are numbers and punctuation.'); + return FALSE; + } + // Extract country code and see if it's correct: + preg_match('/^\+(\d+)/', $number, $matches); + $cc = $matches[1]; + if (strlen($cc) > 3) { + $error = array( + t('Invalid international phone number: Country code "+%cc" is too long; valid country codes are three digits or less.'), + array('%cc' => $cc) + ); + return FALSE; + } + // TODO: Check if parentheses/brackets add up. + return TRUE; +} + +/** + * Formats $number into the standard representation of international + * numbers as per E.123. + * + * @param $number + * International phone number to format + * @return + * Formatted international phone number + */ +function format_int_phone_number($number, $field = array()) { + $number = trim($number); + if ($number === '') { + return ''; + } + $number = _normalize_country_code($number, $field); + $bits = preg_split('/[.()\[\]\- ]/', $number, -1, PREG_SPLIT_NO_EMPTY); + // $bits[0] is the country code WITH a plus sign. + if (isset($bits[1])) { + // This is the first non-CC segment, so it could have the NDN. + switch ($bits[1][0]) { + case 0: + $bits[1] = substr($bits[1], 1); + break; + } + switch ($bits[1]) { + case 0: + case 7: + case 8: + array_splice($bits, 1, 1); + break; + } + } + return implode(' ', $bits); +} + +/** + * Adds a country code to a phone number if necessary. + * + * @param $number + * International or local phone number to format + * @return + * International phone number with country code + */ +function _normalize_country_code($number, $field = array()) { + if ($number[0] !== '+') { + $cc = isset($field['phone_default_country_code']) ? $field['phone_default_country_code'] : '1'; + return "+$cc $number"; + } + return $number; +}