Index: cck_phone.info =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.info,v retrieving revision 1.1 diff -u -r1.1 cck_phone.info --- cck_phone.info 8 Jul 2010 11:20:27 -0000 1.1 +++ cck_phone.info 22 Jul 2010 13:11:15 -0000 @@ -1,7 +1,18 @@ ; $Id: cck_phone.info,v 1.1 2010/07/08 11:20:27 ckng Exp $ -name = Phone Number -description = "The phone module allows administrators to define a CCK field type for phone numbers." +name = Phone number +description = Defines a field type for phone number. package = CCK -dependencies[] = content -core = 6.x - +core = 7.x +files[] = cck_phone.module +files[] = theme/phone-field-view.tpl.php +files[] = includes/cck_phone_countrycodes.inc +files[] = includes/phone.ca.inc +files[] = includes/phone.gb.inc +files[] = includes/phone.my.inc +files[] = includes/phone.ph.inc +files[] = includes/phone.us.inc +files[] = tests/cck_phone.crud.test +files[] = tests/cck_phone.crud_input.test +files[] = tests/phone.gb.test +files[] = tests/phone.my.test +files[] = tests/phone.us.test \ No newline at end of file Index: cck_phone.install =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.install,v retrieving revision 1.1 diff -u -r1.1 cck_phone.install --- cck_phone.install 8 Jul 2010 11:20:27 -0000 1.1 +++ cck_phone.install 23 Jul 2010 11:58:48 -0000 @@ -7,13 +7,12 @@ * Installation file */ - + /** - * Implementation of hook_install(). - */ +* Implementation of hook_install(). +*/ function cck_phone_install() { - drupal_load('module', 'content'); - content_notify('install', 'cck_phone'); + _cck_phone_update_country_code_list(); drupal_set_message(st('Phone number module installed successfully.')); } @@ -21,27 +20,51 @@ * Implementation of hook_uninstall(). */ function cck_phone_uninstall() { - drupal_load('module', 'content'); - content_notify('uninstall', 'cck_phone'); + variable_del('cck_phone_custom_cc'); } /** * Implementation of hook_enable(). - * - * Notify content module when this module is enabled. */ function cck_phone_enable() { // TODO: Migration path for phone.module to cck_phone - drupal_load('module', 'content'); - content_notify('enable', 'cck_phone'); } /** * Implementation of hook_disable(). - * - * Notify content module when this module is disabled. */ function cck_phone_disable() { - drupal_load('module', 'content'); - content_notify('disable', 'cck_phone'); + +} + +/** + * Update list of country codes phone validation. + */ +function cck_phone_update_7000() { + _cck_phone_update_country_code_list(); } + +/** + * Store country code phone validation. + * + * This function should be called only at hook_update_N() + * when new country phone library is added. + */ +function _cck_phone_update_country_code_list() { + // This function is too expensive to call at hook_init() and + // should be called only if there's a new country code added. + + // Load custom country codes phone number includes + $path = drupal_get_path('module', 'cck_phone') .'/includes'; + // Scan include phone numbers directory + $files = file_scan_directory($path, '/^phone\..*\.inc$/'); + + $countrycodes = array(); + foreach ($files as $file) { + list ($dummy, $countrycode) = explode('.', $file->name); + // Faster using array key + $countrycodes[$countrycode] = $countrycode; + } + // Save the list of country codes phone validation + variable_set('cck_phone_custom_cc', $countrycodes); +} \ No newline at end of file Index: cck_phone.module =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.module,v retrieving revision 1.3 diff -u -r1.3 cck_phone.module --- cck_phone.module 12 Jul 2010 09:54:52 -0000 1.3 +++ cck_phone.module 26 Jul 2010 14:19:38 -0000 @@ -3,341 +3,432 @@ /** * @file - * Defines phone number fields for CCK. + * Defines a field type for phone numbers. * Provide some verifications on the phone numbers */ define('CCK_PHONE_PHONE_MIN_LENGTH', 4); // Is there a phone number less than 4 digits? define('CCK_PHONE_PHONE_MAX_LENGTH', 15); // International standard 15 digits define('CCK_PHONE_EXTENSION_MAX_LENGTH', 6); -define('CCK_PHONE_CC_MAX_LENGTH', 2); -define('CCK_PHONE_MOBILE_AGENT', '/(ipod|iphone|android|blackberry|palm|nokia|opera\s+mobi|opera\s+mini|windows\s+ce|iemobile)/i'); +define('CCK_PHONE_TEXTFIELD_MAX_LENGTH', 60); /** - * Implementation of hook_init(). - * This hook is called on module initialization. + * Implements hook_menu(). */ -function cck_phone_init() { - // load country codes - module_load_include('inc', 'cck_phone', 'cck_phone_countrycodes'); - - // load custom country codes phone number includes - $path = drupal_get_path('module', 'cck_phone') .'/includes'; - // scan include phone numbers directory - $files = file_scan_directory($path, '^phone\..*\.inc$'); +function cck_phone_menu() { + $items['cck-phone/autocomplete/%'] = array( + 'page callback' => 'cck_phone_autocomplete', + 'access callback' => 'user_access', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + return $items; +} - $countrycodes = array(); - foreach ($files as $file) { - module_load_include('inc', 'cck_phone', '/includes/'. $file->name); - list ($dummy, $countrycode) = explode('.', $file->name); - // faster using array key - $countrycodes[$countrycode] = $countrycode; +/** + * Menu callback; Retrieve a JSON object containing autocomplete suggestions + * for existing field content. + */ +function cck_phone_autocomplete($string = '') { + $matches = array(); + if ($string) { + $field_name = arg(2); + $column_name = arg(3); + $column = $field_name . '_value'; + $field_table = 'field_data_' . $field_name; + $result = db_select($field_table)->fields($field_table, array($column))->condition($column, db_like($string) . '%', 'LIKE')->range(0, 10)->execute(); + foreach ($result as $field) { + $matches[$field->{$column}] = check_plain($field->{$column}); + } } - - // save the list of country codes phone validation - variable_set('cck_phone_custom_cc', $countrycodes); + drupal_json_output($matches); } /** - * Implementation of hook_theme(). + * Implementation of hook_field_info(). */ -function cck_phone_theme() { +function cck_phone_field_info() { return array( 'phone_number' => array( - 'arguments' => array('element' => NULL), - ), - 'phone_number_extension' => array( - 'arguments' => array('extension' => ''), - ), - 'cck_phone_formatter_default' => array( - 'arguments' => array('element' => NULL), - ), - 'cck_phone_formatter_local' => array( - 'arguments' => array('element' => NULL), - ), - 'cck_phone_mobile_tel' => array( - 'arguments' => array('element' => NULL, 'phone' => ''), + 'label' => t('Phone number'), + 'description' => t('Defines a field type for phone numbers.'), + 'settings' => array( + 'textfield_size' => CCK_PHONE_TEXTFIELD_MAX_LENGTH, + ), + 'instance_settings' => array( + 'default_country' => NULL, + 'all_country_codes' => TRUE, + 'phone_extra' => TRUE, + 'phone_as_link' => TRUE, + ), + 'default_widget' => 'phone_textfield', + 'default_formatter' => 'phone_formatter', ), ); } +/** + * Implements hook_field_settings_form(). + */ +function cck_phone_field_settings_form($field, $instance) { + $form = array(); + $defaults = field_info_field_settings($field['type']); + $settings = array_merge($defaults, $field['settings']); + $form['textfield_size'] = array( + '#type' => 'textfield', + '#title' => t('Size of textfield'), + '#default_value' => $settings['textfield_size'], + '#description' => t('Enter phone number textfield\'s width.'), + ); + return $form; +} + +/** + * Implements hook_field_instance_settings_form(). + */ +function cck_phone_field_instance_settings_form($field, $instance) { + drupal_add_css(drupal_get_path('module', 'cck_phone') . '/css/cck_phone.css'); + drupal_add_js(drupal_get_path('module', 'cck_phone') . '/js/cck_phone.manage_field.js'); + $form = array(); + $defaults = field_info_instance_settings($field['type']); + $settings = array_merge($defaults, $instance['settings']); + $cc_options = _cck_phone_cc_options(TRUE); + $form['default_country'] = array( + '#type' => 'select', + '#title' => t('Default country code'), + '#default_value' => $settings['default_country'], + '#options' => $cc_options, + '#weight' => 1, + ); + $form['all_country_codes'] = array( + '#type' => 'checkbox', + '#title' => t('Show all country codes.'), + '#default_value' => $settings['all_country_codes'], + '#description' => t('Uncheck this to select the country to be displayed.'), + '#weight' => 1.1, + ); + // Country codes settings + $form['country_codes'] = array( + '#type' => 'fieldset', + '#title' => 'Country selection', + '#attributes' => array('class' => array('cck-phone-settings')), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#weight' => 2, + '#description' => t('Country marks with * has custom country code settings and/or validation.'), + ); + $form['country_codes']['country_selection'] = array( + '#type' => 'checkboxes', + '#title' => t('Select country codes to be included'), + '#default_value' => isset($instance['settings']['country_codes']['country_selection']) && !empty($instance['settings']['country_codes']['country_selection']) ? $instance['settings']['country_codes']['country_selection'] : array($instance['settings']['default_country'] => $instance['settings']['default_country']), + '#options' => $cc_options, + ); + $form['phone_extra'] = array( + '#type' => 'checkbox', + '#default_value' => $settings['phone_extra'], + '#title' => t('Add extra phone number\'s description'), + '#weight' => 3, + ); + // We don't need to detect if the device is mobile. RDFA FOAF states: + // A phone, specified using fully qualified tel: URI scheme + // (http://xmlns.com/foaf/spec/#term_phone) + $form['phone_as_link'] = array( + '#type' => 'checkbox', + '#title' => t('Display phone number as link. !foaf: A phone, specified using fully qualified tel: URI scheme', array('!foaf' => l('RDFA FOAF', 'http://xmlns.com/foaf/spec/#term_phone'))), + '#default_value' => $settings['phone_as_link'], + '#weight' => 3, + ); + return $form; +} /** - * Implementation of hook_field_info(). + * Implements hook_field_schema(). */ -function cck_phone_field_info() { +function cck_phone_field_schema($field) { return array( - 'phone_number' => array( - 'label' => t('Phone number'), - 'description' => t('Store a number and country code in the database to assemble a phone number.'), + 'columns' => array( + 'country' => array( + 'type' => 'varchar', + 'length' => 2, + 'not null' => TRUE, + 'description' => t('ISO 3166 2-character country code.'), + ), + 'int_code' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => t('International country calling code.'), + ), + 'value' => array( + 'type' => 'varchar', + 'length' => CCK_PHONE_PHONE_MAX_LENGTH, + 'not null' => TRUE, + 'description' => t('Sanitized phone number with area code.'), + ), + 'extra' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => FALSE, + 'description' => t('Extra phone number\'s description.'), + ), + 'type' => array( + 'type' => 'varchar', + 'length' => 16, + 'not null' => TRUE, + 'description' => t('hCard microformat property indicating the nature of the phone (voice, home, msg, work, pref, fax, cell, video, pager, bbs, modem, car, isdn, pcs).'), + ), + 'hidden' => array( + 'type' => 'char', + 'default' => 0, + 'not null' => FALSE, + 'description' => t('Boolean indicating weather the type is hidden or not.'), + ), + + ), + 'indexes' => array( + 'value_index' => array('value'), ), ); } /** - * Implementation of hook_field_settings(). + * Implements hook_field_validate(). */ -function cck_phone_field_settings($op, $field) { - switch ($op) { - case 'form': - drupal_add_css(drupal_get_path('module', 'cck_phone') . '/cck_phone.css'); - drupal_add_js(drupal_get_path('module', 'cck_phone') . '/cck_phone.js'); - - $form = array(); - $form['default_country'] = array( - '#type' => 'select', - '#title' => t('Default country code'), - '#default_value' => isset($field['default_country']) && ($field['default_country'] !== '') ? $field['default_country'] : NULL, - '#options' => _cck_phone_cc_options(TRUE), - ); - - $form['all_country_codes'] = array( - '#type' => 'checkbox', - '#title' => t('Show all country codes.'), - '#default_value' => isset($field['all_country_codes']) && ($field['all_country_codes'] !== '') ? $field['all_country_codes'] : TRUE, - '#description' => t('Uncheck this to select the country to be displayed.'), - ); - - // Country codes settings - $form['country_codes'] = array( - '#title' => 'Country selection', - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#attributes' => array('class' => 'cck-phone-settings'), - ); - - $form['country_codes']['country_selection'] = array( - '#type' => 'checkboxes', - '#title' => t('Select country codes to be included'), - '#default_value' => isset($field['country_selection']) && !empty($field['country_selection']) ? $field['country_selection'] : array($field['default_country'] => $field['default_country']), - '#options' => _cck_phone_cc_options(TRUE), - '#description' => t('Country marks with * has custom country code settings and/or validation.'), - ); - - $form['enable_custom_country'] = array( - '#type' => 'checkbox', - '#title' => t('Enable country level validation'), - '#default_value' => isset($field['enable_custom_country']) && ($field['enable_custom_country'] !== '') ? $field['enable_custom_country'] : TRUE, - '#description' => t('Uncheck this to disable stringent country phone number validation.'), - ); - - $form['enable_extension'] = array( - '#type' => 'checkbox', - '#title' => t('Enable phone extension support'), - '#default_value' => isset($field['enable_extension']) && ($field['enable_extension'] !== '') ? $field['enable_extension'] : FALSE, - '#description' => t('Check this to enable phone number extension field.'), - ); - - $form['enable_mobile'] = array( - '#type' => 'checkbox', - '#title' => t('Enable mobile device detection'), - '#default_value' => isset($field['enable_mobile']) && ($field['enable_mobile'] !== '') ? $field['enable_mobile'] : FALSE, - '#description' => t('Check this to enable phone number link on mobile browsers (RFC3966).'), - ); - - // Display country specific settings - foreach (_cck_phone_custom_cc() as $cc) { - $function = $cc . '_phone_field_settings'; - if (function_exists($function)) { - $country_settings = $function($op, $field); - if (isset($country_settings) && !empty($country_settings)) { - $country_codes = cck_phone_countrycodes($cc); - // Wrap with fieldset - $wrapper = array( - '#title' => $country_codes['country'] . ' specific settings', - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#attributes' => array('class' => 'cck-phone-settings cck-phone-settings-' . $cc), +function cck_phone_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { + $field_name = $field['field_name']; + foreach ($items as $delta => $item) { + $phone_value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); + if (!empty($phone_value)) { + $subaddress_value = check_plain($item['subaddress_value']); + // Lenient checking, as long as it doesn't have invalid phone number characters + $regex = '/^ + [+\s.()-]* # optional separator + (?: # } + \d # } 4-15 digits number + [\s.()-]* # } each followed by optional separator + ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } + $/x'; + // Generic number validation + if (!preg_match($regex, $phone_value)) { + $errors[$field_name][$langcode][$delta][] = array( + 'error' => 'value', + 'message' => t('Phone number must be numeric and %min_length to %max_length length.', array('%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH)), + ); + } + else { + $code = $item['country']; + // Custom country level validation + $validate_function = $code . '_validate_number'; + $has_cc = module_load_include('inc', 'cck_phone', 'includes/phone.' . $code) && function_exists($validate_function); + if ($has_cc) { + if (!$validate_function($phone_value, '', $error_message)) { + $errors[$field_name][$langcode][$delta][] = array( + 'error' => 'value', + 'message' => $error_message, ); - $wrapper[] = $country_settings; - array_push($form, $wrapper); } } } - - return $form; - - case 'validate': - // Validate country specific settings - foreach (_cck_phone_custom_cc() as $cc) { - $function = $cc . '_phone_field_settings'; - if (function_exists($function)) { - $function($op, $field); - } - } - break; - - case 'save': - $settings = array('default_country', 'all_country_codes', 'country_selection', 'enable_custom_country', 'enable_extension', 'enable_mobile'); - - // Save country specific settings - foreach (_cck_phone_custom_cc() as $cc) { - $function = $cc . '_phone_field_settings'; - if (function_exists($function)) { - array_push($settings, $function($op, $field)); - } - } - return $settings; - - // TODO: filters for phone number? -// case 'filters': -// break; - - case 'database columns': - return array( - 'number' => array( - 'type' => 'varchar', - 'length' => CCK_PHONE_PHONE_MAX_LENGTH, - 'not null' => FALSE, - ), - 'country_codes' => array( - 'type' => 'varchar', - 'length' => CCK_PHONE_CC_MAX_LENGTH, - 'not null' => FALSE, - ), - 'extension' => array( - 'type' => 'varchar', - 'length' => CCK_PHONE_EXTENSION_MAX_LENGTH, - 'not null' => FALSE, - ), - ); + } } } /** - * Implementation of hook_field(). - */ -function cck_phone_field($op, &$node, $field, &$items, $teaser, $page) { - switch ($op) { - case 'validate': - foreach ($items as $delta => $value) { - _cck_phone_validate($items[$delta], $delta, $field, $node); - } - - return $items; - break; - - case 'presave': - foreach ($items as $delta => $value) { - _cck_phone_process($items[$delta], $delta, $field, $node); - } - break; - - // Do country level code need to modify the output? - case 'sanitize': - foreach ($items as $delta => $value) { - _cck_phone_sanitize($items[$delta], $delta, $field, $node); - } - break; + * Implements hook_field_widget_error(). + */ +function cck_phone_field_widget_error($element, $error, $form, &$form_state) { + $element['#parents'][] = $error['error']; + form_error($element, $error['message'], $form, $form_state); +} +/** + * Implements hook_field_presave(). + */ +function cck_phone_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { + module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); + $list = cck_phone_countrycodes(); + foreach ($items as $delta => $item) { + $code = $item['country']; + $value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); + $sanitize_number_function = $code . '_sanitize_number'; + if (function_exists($sanitize_number_function)) { + $sanitize_number_function($value); + } + $items[$delta]['value'] = $value; + $items[$delta]['int_code'] = (int) preg_replace('/^\+/', '', $list[$code]['code']); + $items[$delta]['extra'] = t($items[$delta]['extra']); + $items[$delta]['type'] = t($items[$delta]['type']); + $items[$delta]['hidden'] = (bool) $items[$delta]['hidden']; } +} +/** + * Implements hook_field_is_empty(). + */ +function cck_phone_field_is_empty($item, $field) { + return empty($item['value']); } +/************************************************************************** + * Field Type API: Widget + * + * The widget is the form element used to receive input from the user + * when the field is being populated. + **************************************************************************/ /** - * Implementation of hook_field_formatter_info(). + * Implement hook_field_widget_info(). */ -function cck_phone_field_formatter_info() { +function cck_phone_field_widget_info() { return array( - 'default' => array( - 'label' => 'Global phone number (default)', + 'phone_textfield' => array( + 'label' => t('Textfield'), 'field types' => array('phone_number'), - 'multiple values' => CONTENT_HANDLE_CORE, ), - 'local' => array( - 'label' => 'Local phone number', + 'phone_autocomplete' => array( + 'label' => t('Autocomplete'), 'field types' => array('phone_number'), - 'multiple values' => CONTENT_HANDLE_CORE, - ), + ), ); } /** - * Theme function for phone extension. + * Implements hook_field_widget_form(). */ -function theme_phone_number_extension($extension = '') { - return t(' ext. @extension', array('@extension' => $extension)); +function cck_phone_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { + $field_name = $field['field_name']; + $elements = array(); + // Microformats hCard tel types (http://microformats.org/wiki/hcard) + $type = array( + 'Voice' => t('Voice number'), + 'Home' => t('Home'), + 'Work' => t('Work'), + 'Fax' => t('Fax'), + 'Pref' => t('Preferred number'), + 'Pager' => t('Pager'), + 'Msg' => t('Telephone with answering machine'), + 'Video' => t('Video conferencing system'), + 'BBS' => t('Bulletin board system'), + 'ISDN' => t('ISDN'), + 'Modem' => t('Modem'), + 'Car' => t('Car phone number'), + 'PCS' => t('Personal communication services number'), + ); + $elements['phone_field'] = $element; + $elements['phone_field']['#type'] = 'item'; + $elements['phone_field']['value'] = array( + '#type' => 'textfield', + '#size' => $field['settings']['textfield_size'] ? $field['settings']['textfield_size'] : CCK_PHONE_TEXTFIELD_MAX_LENGTH, + '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, + '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '', + '#parents' => array($field_name, $langcode, $delta, 'value'), + ); + if ($instance['widget']['type'] == 'phone_autocomplete') { + $elements['phone_field']['value']['#autocomplete_path'] = 'cck-phone/autocomplete/' . $field_name; + } + $elements['phone_field']['phone_advance'] = array( + '#type' => 'fieldset', + '#title' => t('Phone number options'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $elements['phone_field']['phone_advance']['country'] = array( + '#type' => 'select', + '#title' => t('Country code'), + '#default_value' => isset($items[$delta]['country']) ? $items[$delta]['country'] : $instance['settings']['default_country'], + '#parents' => array($field_name, $langcode, $delta, 'country'), + ); + if ($instance['settings']['all_country_codes']) { + $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(); + } + else { + $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(FALSE, $instance['settings']['country_codes']['country_selection']); + } + $elements['phone_field']['phone_advance']['type'] = array( + '#type' => 'select', + '#options' => $type, + '#title' => t('Select phone type'), + '#default_value' => isset($items[$delta]['type']) ? $items[$delta]['type'] : 'Voice', + '#parents' => array($field_name, $langcode, $delta, 'type'), + ); + $elements['phone_field']['phone_advance']['hidden'] = array( + '#type' => 'checkbox', + '#title' => t('Hide phone type'), + '#default_value' => isset($items[$delta]['hidden']) && $items[$delta]['hidden'], + '#parents' => array($field_name, $langcode, $delta, 'hidden'), + ); + if ($instance['settings']['phone_extra']) { + $elements['phone_field']['phone_advance']['extra'] = array( + '#type' => 'textfield', + '#title' => t('Annotation'), + '#size' => 60, + '#maxlength' => 255, + '#default_value' => isset($items[$delta]['extra']) ? $items[$delta]['extra'] : '', + '#parents' => array($field_name, $langcode, $delta, 'extra'), + '#description' => t($field['columns']['extra']['description']), + ); + } + return $elements; } +/*********************************************************************** + * Field Type API: Formatter + * + * These are the api hooks that present formatted (themed) output to the + * user. + **********************************************************************/ /** - * Theme function for mobile tel. + *Implementation of hook_field_formatter_info(). */ -function theme_cck_phone_mobile_tel($element, $phone = '') { - $item = $element['#item']; - - // Mobile browsers support - if (isset($item['mobile_output']) && $item['mobile_output'] == TRUE) { - // Always output as global phone number without separator, leave the $phone display unchanged - $cc = cck_phone_countrycodes($item['country_codes']); - $tel = $cc['code'] . $item['number']; - - $phone = '' . $phone . ''; - } - - return $phone; +function cck_phone_field_formatter_info() { + return array( + 'phone_formatter' => array( + 'label' => t('Phone number'), + 'field types' => array('phone_number'), + ), + ); } /** - * Theme function for 'default' or global phone number field formatter. + * Implements hook_field_formatter_view(). */ -function theme_cck_phone_formatter_default($element) { - $item = $element['#item']; - $phone = ''; - - // Display a global phone number with country code. - if (!empty($item['number']) && !empty($item['country_codes'])) { - // Call country default formatter if exist - $function = $item['country_codes'] . '_formatter_default'; - if (function_exists($function)) { - $phone = $function($element); +function cck_phone_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) { + $element = array(); + $type_class = array('type'); + foreach ($items as $delta => $item) { + $code = $item['country']; + $int_code = $item['int_code']; + $tel_value = '+' . $item['int_code'] . $item['value']; + $formatter_default_function = $code . '_formatter_default'; + module_load_include('inc', 'cck_phone', 'includes/phone.' . $code); + if (function_exists($formatter_default_function)) { + $format = $formatter_default_function($item['value']); } else { - $cc = cck_phone_countrycodes($item['country_codes']); - $phone = $cc['code'] .'-'. $item['number']; + $format = $item['value']; } - - // Extension - if (!empty($item['extension'])) { - $phone = $phone . theme('phone_number_extension', $item['extension']); - } - - // Mobile browsers support - $phone = theme('cck_phone_mobile_tel', $element, $phone); + $details = array( + 'value' => $format, + 'int_code' => $int_code, + 'tel_value' => $tel_value, + 'type' => $item['type'], + 'extra' => $item['extra'], + 'type_attr' => array('class' => $item['hidden'] ? $type_class[] = 'element-invisible' : $type_class), + ); + $element[$delta]['#markup'] = theme('phone_field_view', array('phone' => $details)); } - - return $phone; + return $element; } /** - * Theme function for 'local' phone number field formatter. + * Implementation of hook_theme() */ -function theme_cck_phone_formatter_local($element) { - $item = $element['#item']; - $phone = ''; - - // Display a local phone number without country code. - if (!empty($item['number'])) { - // Call country local formatter if exist - $function = $item['country_codes'] . '_formatter_local'; - if (function_exists($function)) { - $phone = $function($element); - } - else { - $phone = $item['number']; - } - - // Extension - if (!empty($item['extension'])) { - $phone = $phone . theme('phone_number_extension', $item['extension']); - } - - // Mobile browsers support - $phone = theme('cck_phone_mobile_tel', $element, $phone); - } - - return $phone; +function cck_phone_theme($existing, $type, $theme, $path) { + return array( + 'phone_field_view' => array( + 'render element' => 'phone', + 'template' => 'phone-field-view', + 'path' => drupal_get_path('module', 'cck_phone') . '/theme', + ), + ); } /** @@ -350,16 +441,19 @@ * @return string */ function _cck_phone_cc_options($show_custom = FALSE, $country_selection = array()) { + // Load country codes + module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); + $options = array(); - if ($show_custom) { $custom_cc = _cck_phone_custom_cc(); } - - foreach (cck_phone_countrycodes() as $cc => $value) { + + $list = cck_phone_countrycodes(); + foreach ($list as $cc => $value) { $cc_name = $value['country'] .' ('. $value['code'] .')'; - // faster using array key instead of in_array + // Faster using array key instead of in_array if ($show_custom && isset($custom_cc[$cc])) { $cc_name .= ' *'; } @@ -380,401 +474,9 @@ * Array of country codes abbreviation or FALSE if none exist. */ function _cck_phone_custom_cc() { - static $cc; - + $cc = &drupal_static(__FUNCTION__); if (!isset($cc)) { $cc = variable_get('cck_phone_custom_cc', FALSE); } - return $cc; -} - -function _cck_phone_valid_input($input) { - // lenient checking, as long as don't have invalid phone number character - $regex = '/^ - [\s.()-]* # optional separator - (?: # } - \d # } 4-15 digits number - [\s.()-]* # } each followed by optional separator - ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } - $/x'; - - return preg_match($regex, $input); -} - -function _cck_phone_valid_cc_input($list, $cc) { - if (isset($list[$cc]) && $list[$cc] == $cc) { - return TRUE; - } - - return FALSE; -} - -function _cck_phone_validate(&$item, $delta, $field, $node) { - $phone_input = trim($item['number']); - $countrycode = trim($item['country_codes']); - $ext_input = ''; - if ($field['enable_extension']) { - $ext_input = trim($item['extension']); - } - - if ($phone_input && !(isset($field['widget']['default_value'][$delta]['number']) && $phone_input == $field['widget']['default_value'][$delta]['number'] && !$field['required'])) { - - $error_params = array( - '%phone_input' => check_plain($phone_input), // original phone input - '%countrycode' => check_plain($countrycode), - '%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, - '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH, - '%ext_input' => check_plain($ext_input), - '%ext_max_length' => CCK_PHONE_EXTENSION_MAX_LENGTH, - ); - - // Only allow digit, dash, space and bracket - if (!_cck_phone_valid_input($phone_input, $ext_input)) { - $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); - if ($field['enable_extension'] && $ext_input != '') { - $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); - } - - form_set_error($field['field_name'], $error); - } - else { - if (!$field['all_country_codes']) { - if (!_cck_phone_valid_cc_input($field['country_selection'], $countrycode)) { - $error = t('Invalid country code "%countrycode" submitted.', $error_params); - form_set_error($field['field_name'], $error); - } - } - // Generic number validation - if (!cck_phone_validate_number($countrycode, $phone_input, $ext_input)) { - $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); - if ($field['enable_extension'] && $ext_input != '') { - $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); - } - - form_set_error($field['field_name'], $error); - } - // Country level validation if enabled - elseif ($field['enable_custom_country'] != 0 || is_null($field['enable_custom_country']) || !isset($field['enable_custom_country'])) { - $custom_cc = _cck_phone_custom_cc(); - - if (isset($custom_cc[$countrycode])) { - $validate_function = $countrycode . '_validate_number'; - - if (function_exists($validate_function)) { - $error = ''; - if (!$validate_function($phone_input, $ext_input, $error)) { - form_set_error($field['field_name'], t($error, $error_params)); - } - } - } - } - } - } -} - -function _cck_phone_process(&$item, $delta = 0, $field, $node) { - $widget = $field['widget']['default_value'][$delta]; - // Clean up the phone number. - $item['number'] = cck_phone_clean_number($item['number']); - $item['extension'] = cck_phone_clean_number($item['extension']); - - // Don't save an invalid default value. - if ((isset($widget['number']) && $item['number'] == $widget['number']) && (isset($widget['country_codes']) && $item['country_codes'] == $widget['country_codes']) && is_object($node)) { - if (!cck_phone_validate_number($item['country_codes'], $item['number'], $item['extension'])) { - unset($item['number']); - unset($item['country_codes']); - unset($item['extension']); - } - } -} - -/** - * Cleanup user-entered values for a phone number field according to field settings. - * - * @param $item - * A single phone number item, usually containing number and country code. - * @param $delta - * The delta value if this field is one of multiple fields. - * @param $field - * The CCK field definition. - * @param $node - * The node containing this phone number. - */ -function _cck_phone_sanitize(&$item, $delta, &$field, &$node) { - if (!empty($item['number'])) { - $cc = $item['country_codes']; - $item['number'] = cck_phone_clean_number($item['number']); - - $custom_cc = _cck_phone_custom_cc(); - if (isset($custom_cc[$cc])) { - $function = $cc . '_sanitize_number'; - - if (function_exists($function)) { - $function($item['number']); - } - } - } - - if ($field['enable_extension']) { - $item['extension'] = cck_phone_clean_number($item['extension']); - } - else { - unset($item['extension']); - } - - if ($field['enable_mobile'] && preg_match(CCK_PHONE_MOBILE_AGENT, drupal_strtolower($_SERVER['HTTP_USER_AGENT']))) { - $item['mobile_output'] = TRUE; - } -} - - -/** - * Implementation of hook_widget_info(). - */ -function cck_phone_widget_info() { - return array( - 'phone_number' => array( - 'label' => t('Phone number'), - 'field types' => array('phone_number'), - 'multiple values' => CONTENT_HANDLE_CORE, - ), - ); -} - -/** - * Implementation of hook_widget_settings(). - */ -function cck_phone_widget_settings($op, $widget) { - switch ($op) { - case 'form': - $form = array(); - $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : CCK_PHONE_PHONE_MAX_LENGTH; - $form['input']['size'] = array( - '#type' => 'textfield', - '#title' => t('Size of phone number textfield'), - '#default_value' => $size, - '#element_validate' => array('_element_validate_integer_positive'), - '#required' => TRUE, - '#description' => t('International number is maximum 15 digits with additional country code, default is %length.', array('%length' => CCK_PHONE_PHONE_MAX_LENGTH)), - ); - return $form; - - case 'save': - return array('size'); - } -} - -/** - * Implementation of hook_widget(). - */ -function cck_phone_widget(&$form, &$form_state, $field, $items, $delta = 0) { - $element = array( - '#type' => $field['widget']['type'], - '#default_value' => isset($items[$delta]) ? $items[$delta] : '', - '#title' => $field['widget']['label'], - '#weight' => $field['widget']['weight'], - '#description' => $field['widget']['description'], - '#required' => $field['required'], - '#field' => $field, - ); - return $element; -} - -/** - * Implementation of hook_content_is_empty(). - */ -function cck_phone_content_is_empty($item, $field) { - if (empty($item['number'])) { - return TRUE; - } - return FALSE; -} - -/** - * Implementation of FAPI hook_elements(). - */ -function cck_phone_elements() { - return array( - 'phone_number' => array( - '#input' => TRUE, - '#process' => array('cck_phone_process'), - '#autocomplete_path' => FALSE, - ), - ); -} - -/** - * FAPI theme for an individual phone number elements. - * - * The phone number is already rendered by the themes and the html - * output lives in $element['#children']. Override this theme to - * make custom changes to the output. - * - * $element['#title'] is the field title - * $element['#field_name'] contains the field name - * $element['#delta''] is the position of this element in the group - * $element['number] is the phone number - * $element['country_codes'] is the country code - */ -function theme_phone_number($element) { - drupal_add_css(drupal_get_path('module', 'cck_phone') .'/cck_phone.css'); - - // Prefix single value phone number fields with the name of the field. -// if (empty($element['#field']['multiple'])) { -// if (isset($element['number']) && isset($element['country_codes'])) { -// $element['number']['#title'] = $element['#title'] .' '. $element['number']['#title']; -// $element['country_codes']['#title'] = $element['#title'] .' '. $element['country_codes']['#title']; -// } -// elseif ($element['number']) { -// $element['number']['#title'] = $element['#title']; -// } -// } - - $output = ''; - - $output = '
*' : ''; - - if (!empty($element['#title'])) { - $title = $element['#title']; - if (!empty($element['number']['#id'])) { - $output .= ' \n"; - } - else { - $output .= ' \n"; - } - } - - $output .= '
'; - if (isset($element['number'])) { - $output .= '
'. theme('textfield', $element['number']) .'
'; - } - if (isset($element['extension'])) { - $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : ''; - $output .= '
'. $prefix . theme('textfield', $element['extension']) .'
'; - } - $output .= '
'. theme('select', $element['country_codes']) .'
'; - $output .= '
'; - - return $output; -} - -/** - * Process an individual element. - */ -function cck_phone_process($element, $edit, $form_state, $form) { - $field_name = $element['#field_name']; - $field = $form['#field_info'][$field_name]; - $field_key = $element['#columns'][0]; - $delta = $element['#delta']; - - $element['number'] = array( - '#type' => 'textfield', - '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, - '#size' => CCK_PHONE_PHONE_MAX_LENGTH, -// '#title' => t('Number'), - '#description' => $element['#description'], - '#required' => ($delta == 0 && $field['number'] !== 'optional') ? $element['#required'] : FALSE, - '#default_value' => isset($element['#value']['number']) ? $element['#value']['number'] : NULL, - ); - - if ($field['enable_extension']) { - $element['extension'] = array( - '#type' => 'textfield', - '#maxlength' => CCK_PHONE_EXTENSION_MAX_LENGTH, - '#size' => CCK_PHONE_EXTENSION_MAX_LENGTH, -// '#title' => t('ext'), - '#required' => FALSE, - '#default_value' => isset($element['#value']['extension']) ? $element['#value']['extension'] : NULL, - '#prefix' => '
'. t('ext') .'
', - ); - } - - $element['country_codes'] = array( - '#type' => 'select', -// '#title' => 'Country code', - '#default_value' => ($element['#value']['number'] != '' && isset($element['#value']['country_codes'])) ? $element['#value']['country_codes'] : (isset($field['default_country']) ? $field['default_country'] : NULL), - ); - if ($field['all_country_codes']) { - $element['country_codes']['#options'] = _cck_phone_cc_options(); - } - else { - $element['country_codes']['#options'] = _cck_phone_cc_options(FALSE, $field['country_selection']); - } - - return $element; -} - -/** - * Strip number of space, hash, dash, bracket, etc leaving digit only. - * - * @param string $number - * @return string Returns digit only phone number. - */ -function cck_phone_clean_number($number) { - // Remove none numeric characters - $number = preg_replace('/[^0-9]/', '', $number); - - return $number; -} - -/** - * Generic validation for Phone Number. - * - * @param string $countrycode - * @param string $number - * @return boolean Returns boolean FALSE if the phone number is not valid. - */ -function cck_phone_validate_number($countrycode, $number, $ext = '') { - // We don't want to worry about separators - $number = cck_phone_clean_number($number); - if ($number !== '' && drupal_strlen($number) > CCK_PHONE_PHONE_MAX_LENGTH) { - return FALSE; - } - - $ext = cck_phone_clean_number($ext); - if ($ext !== '' && drupal_strlen($ext) > CCK_PHONE_EXTENSION_MAX_LENGTH) { - return FALSE; - } - - return TRUE; -} - - -/* ------ Token ------ */ - -/** - * Implementation of hook_token_list(). - */ -function cck_phone_token_list($type = 'all') { - if ($type == 'field' || $type == 'all') { - $tokens = array(); - - $tokens['cck_phone']['number'] = t('Phone number'); - $tokens['cck_phone']['country_codes'] = t('Country code'); - $tokens['cck_phone']['extension'] = t('Extension'); - - return $tokens; - } -} - -/** - * Implementation of hook_token_values(). - */ -function cck_phone_token_values($type, $object = NULL, $options = array()) { - if ($type == 'field') { - $item = $object[0]; - - $tokens['number'] = $item['number']; - $tokens['country_codes'] = $item['country_codes']; - $tokens['cck_phone']['extension'] = $item['extension']; - - return $tokens; - } -} +} \ No newline at end of file Index: includes/phone.ca.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.ca.inc,v retrieving revision 1.1 diff -u -r1.1 phone.ca.inc --- includes/phone.ca.inc 8 Jul 2010 11:22:37 -0000 1.1 +++ includes/phone.ca.inc 24 Jul 2010 06:02:20 -0000 @@ -7,23 +7,25 @@ */ /** - * Verifies that $number is a valid ten-digit North American phone number. + * Validate country level phone number. * * @param $number - * Digits only value. - * @param $ext - * Digits only value. + * Digits only phone number value. + * @param $subaddress + * Subaddress value for telephone/fax's extension number, ISDN subaddress, + * fax's T33 subaddress, modem's parameters/recommended parameters. + * Reference: http://tools.ietf.org/html/rfc2806. * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number + * Error message that will be displayed to user. + * @param $phone_type + * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, + * Pager, BBS, Modem, Car, ISDN, PCS) * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * TRUE if it is a valid phone number for this country, FALSE otherwise. */ -function ca_validate_number($number, $ext = '', &$error) { - return us_validate_number($number, $ext = '', &$error); +function ca_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { + module_load_include('inc', 'cck_phone', 'includes/phone.us'); + return us_validate_number($number, $subaddress, $error, $phone_type); } /** @@ -33,43 +35,17 @@ * A single phone number item. */ function ca_sanitize_number(&$number) { + module_load_include('inc', 'cck_phone', 'includes/phone.us'); us_sanitize_number($number); } /** * Default formatter for international phone number. * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. - */ -function ca_formatter_default($element) { - return us_formatter_default($element); -} - -/** - * Local formatter for local phone number. - * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * @param $number + * Phone number. */ -function ca_formatter_local($element) { - return us_formatter_local($element); +function ca_formatter_default($number) { + module_load_include('inc', 'cck_phone', 'includes/phone.us'); + return us_formatter_default($number); } \ No newline at end of file Index: includes/phone.gb.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.gb.inc,v retrieving revision 1.1 diff -u -r1.1 phone.gb.inc --- includes/phone.gb.inc 8 Jul 2010 11:22:37 -0000 1.1 +++ includes/phone.gb.inc 24 Jul 2010 07:12:33 -0000 @@ -25,29 +25,27 @@ * Validate country level phone number. * * @param $number - * Digits only value. - * @param $ext - * Digits only value. + * Digits only phone number value. + * @param $subaddress + * Subaddress value for telephone/fax's extension number, ISDN subaddress, + * fax's T33 subaddress, modem's parameters/recommended parameters. + * Reference: http://tools.ietf.org/html/rfc2806. * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number + * Error message that will be displayed to user. + * @param $phone_type + * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, + * Pager, BBS, Modem, Car, ISDN, PCS) * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * TRUE if it is a valid phone number for this country, FALSE otherwise. */ -function gb_validate_number($number, $ext = '', &$error) { - // We don't want to worry about separators - $number = cck_phone_clean_number($number); - - if (preg_match(_uk_phone_rules(), $number)) { - return TRUE; +function gb_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { + if (!empty($number)) { + if (preg_match(_uk_phone_rules(), $number)) { + return TRUE; + } + $error = t('"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "29 9999 9999", with optional leading "0"', array('%phone_input' => $number)); + return FALSE; } - - // t() is no needed - $error = '"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "99 9999 9999", with optional leading "0"'; - return FALSE; } /** @@ -64,58 +62,16 @@ /** * Default formatter for international phone number. * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. - */ -function gb_formatter_default($element) { - $item = $element['#item']; - - // Display a global phone number with country code. - $cc = cck_phone_countrycodes($item['country_codes']); - - $result = preg_match(_uk_phone_rules, $item['number'], $matches); - - if ($result) { - // output as +44 AA BBBB CCCC, +44 AAA BBB CCCC or +44 AAAA BBB CCC - $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; - } - - return $phone; -} - - -/** - * Local formatter for local phone number. - * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * @param $number + * Phone number. */ -function gb_formatter_local($element) { - // Display a local phone number without country code. - $result = preg_match(_uk_phone_rules, $item['number'], $matches); +function gb_formatter_default($number) { + $result = preg_match(_uk_phone_rules(), $number, $matches); if ($result) { - // output as 0AA BBBB CCCC, 0AAA BBB CCCC or 0AAAA BBB CCC - $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; + // output as AA BBBB CCCC, AAA BBB CCCC or AAAA BBB CCC + $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; } return $phone; -} +} \ No newline at end of file Index: includes/phone.my.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.my.inc,v retrieving revision 1.1 diff -u -r1.1 phone.my.inc --- includes/phone.my.inc 8 Jul 2010 11:22:37 -0000 1.1 +++ includes/phone.my.inc 24 Jul 2010 07:08:18 -0000 @@ -45,78 +45,64 @@ } /** - * Verifies that $number is a valid Malaysia phone number. + * Validate country level phone number. * * @param $number - * Digits only value. - * @param $ext - * Digits only value. + * Digits only phone number value. + * @param $subaddress + * Subaddress value for telephone/fax's extension number, ISDN subaddress, + * fax's T33 subaddress, modem's parameters/recommended parameters. + * Reference: http://tools.ietf.org/html/rfc2806. * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number + * Error message that will be displayed to user. + * @param $phone_type + * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, + * Pager, BBS, Modem, Car, ISDN, PCS) * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * TRUE if it is a valid phone number for this country, FALSE otherwise. */ -function my_validate_number($number, $ext = '', &$error) { - // We don't want to worry about separators - $number = cck_phone_clean_number($number); - - foreach (_my_phone_rules() as $rule) { - // define regular expression - $regex = '/^ - ([0]*) # an optional 0 - ('. $rule[0] .') # area code - \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] - $/x'; - - $result = preg_match($regex, $number, $matches); - - if ($result) { - return TRUE; +function my_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { + if (!empty($number)) { + foreach (_my_phone_rules() as $rule) { + // define regular expression + $regex = '/^ + ([0]*) # an optional 0 + ('. $rule[0] .') # area code + \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] + $/x'; + + $result = preg_match($regex, $number, $matches); + + if ($result) { + return TRUE; + } } + $error = t('"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.', array('%phone_input' => $number)); + return FALSE; } - - // t() is no needed - $error = '"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.'; - return FALSE; } /** - * Cleanup user-entered values for a phone number field for saving to DB. + * Cleanup user-entered values for a phone number field for storing to DB. * * @param $number * A single phone number item. + * @param $href + * Valid number (numeric and + charaters only) placed at + * href="tel:;ext=123" of anchor tag. */ function my_sanitize_number(&$number) { // Remove trunk prefix '0' - $number = preg_replace('/^([0]*)/', '', $number); } /** * Default formatter for international phone number. * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * @param $number + * Phone number. */ -function my_formatter_default($element) { - $item = $element['#item']; - - // Display a global phone number with country code. - $cc = cck_phone_countrycodes($item['country_codes']); - +function my_formatter_default($number) { // Format the phone number however you like, this is the default foreach (_my_phone_rules() as $rule) { // define regular expression @@ -125,55 +111,14 @@ (\d{3,4}) (\d{4}) $/x'; - - $result = preg_match($regex, $item['number'], $matches); + $result = preg_match($regex, $number, $matches); if ($result) { - // output as +60A-BBB CCCC or +60A-BBBB CCCC - $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; + // output as A-BBB CCCC + $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; continue; } } - - return $phone . $ext; -} - -/** - * Local formatter for local phone number. - * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. - */ -function my_formatter_local($element) { - // Display a local phone number without country code. - $phone = $element['#item']['number']; - - foreach (_my_phone_rules() as $rule) { - // define regular expression - $regex = '/^ - ('. $rule[0] .') # area code - (\d{3,4}) - (\d{4}) - $/x'; - - $result = preg_match($regex, $phone, $matches); - - if ($result) { - // output as 0A-BBB CCCC or 0A-BBBB CCCC - $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; - continue; - } - } - return $phone; -} +} \ No newline at end of file Index: includes/phone.us.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.us.inc,v retrieving revision 1.1 diff -u -r1.1 phone.us.inc --- includes/phone.us.inc 8 Jul 2010 11:22:37 -0000 1.1 +++ includes/phone.us.inc 24 Jul 2010 06:51:51 -0000 @@ -7,48 +7,45 @@ */ /** - * Verifies that $number is a valid ten-digit North American phone number. + * Validate country level phone number. * * @param $number - * Digits only value. - * @param $ext - * Digits only value. + * Digits only phone number value. + * @param $subaddress + * Subaddress value for telephone/fax's extension number, ISDN subaddress, + * fax's T33 subaddress, modem's parameters/recommended parameters. + * Reference: http://tools.ietf.org/html/rfc2806. * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number + * Error message that will be displayed to user. + * @param $phone_type + * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, + * Pager, BBS, Modem, Car, ISDN, PCS) * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * TRUE if it is a valid phone number for this country, FALSE otherwise. */ -function us_validate_number($number, $ext = '', &$error) { - // Don't need to check for extension because it has been checked by generic validation as all digits, unless has special format/requirements - // We don't want to worry about separators - $number = cck_phone_clean_number($number); - - // define regular expression - $regex = '/^ - ([1]*) # an optional 1 - [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) - [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) - \d{4} # 4-digit line number - $/x'; - - $result = preg_match($regex, $number, $matches); - - if ($result && $matches[1] == '') { - return TRUE; - } - elseif ($result && $matches[1] == '1') { - // t() is no needed - $error = 'Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'; - return FALSE; - } - else { - // t() is no needed - $error = '"%phone_input" is not a valid North American phone number, it should be 10 digits number like "999 999 9999"'; - return FALSE; +function us_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { + if (!empty($number)) { + // Define regular expression + $regex = '/^ + ([1]*) # an optional 1 + [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) + [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) + \d{4} # 4-digit line number + $/x'; + + $result = preg_match($regex, $number, $matches); + + if ($result && $matches[1] == '') { + return TRUE; + } + elseif ($result && $matches[1] == '1') { + $error = t('Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'); + return FALSE; + } + else { + $error = t('%phone_input is not a valid North American phone number, it should be 10 digits number like "989 999 9999"', array('%phone_input' => $number)); + return FALSE; + } } } @@ -68,25 +65,10 @@ /** * Default formatter for international phone number. * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. + * @param $number + * Phone number. */ -function us_formatter_default($element) { - $item = $element['#item']; - $phone = ''; - - // Display a global phone number with country code. - $cc = cck_phone_countrycodes($item['country_codes']); - +function us_formatter_default($number) { // Format the phone number however you like, this is the default // define regular expression $regex = '/^ @@ -95,43 +77,7 @@ (\d{4}) # 4-digit line number /x'; - $result = preg_match($regex, $item['number'], $matches); - - if ($result) { - // output as +1 (AAA) BBB CCCC - $phone = $cc['code'] .' ('. $matches[1] .') '. $matches[2] .' '. $matches[3]; - } - - return $phone . $ext; -} - -/** - * Local formatter for local phone number. - * - * @param $element - * $element['#item']['country_codes']: alpha-2 country code - * $element['#item']['number']: phone number - * @param $error - * The error message to shown to user. - * Available parameters to use in the error message are - * - "%countrycode": the alpha-2 CC - * - "%phone_input": the original number input by user (could be invalid) - * - "%max_length": allowed maximum length of the phone number - * @return boolean - * TRUE if it is a valid phone number for that country, FALSE otherwise. - */ -function us_formatter_local($element) { - $item = $element['#item']; - $phone = ''; - - // Display a local phone number without country code. - $regex = '/^ - ([2-9][0-8]\d) # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) - ([2-9]\d{2}) # 3-digit prefix (cannot start with 0 or 1) - (\d{4}) # 4-digit line number - /x'; - - $result = preg_match($regex, $item['number'], $matches); + $result = preg_match($regex, $number, $matches); if ($result) { // output as (AAA) BBB CCCC @@ -139,4 +85,4 @@ } return $phone; -} +} \ No newline at end of file --- cck_phone hcard.patch +++ cck_phone hcard.patch @@ -0,0 +1,7982 @@ +Index: cck_phone.info +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.info,v +retrieving revision 1.1 +diff -u -r1.1 cck_phone.info +--- cck_phone.info 8 Jul 2010 11:20:27 -0000 1.1 ++++ cck_phone.info 22 Jul 2010 13:11:15 -0000 +@@ -1,7 +1,18 @@ + ; $Id: cck_phone.info,v 1.1 2010/07/08 11:20:27 ckng Exp $ +-name = Phone Number +-description = "The phone module allows administrators to define a CCK field type for phone numbers." ++name = Phone number ++description = Defines a field type for phone number. + package = CCK +-dependencies[] = content +-core = 6.x +- ++core = 7.x ++files[] = cck_phone.module ++files[] = theme/phone-field-view.tpl.php ++files[] = includes/cck_phone_countrycodes.inc ++files[] = includes/phone.ca.inc ++files[] = includes/phone.gb.inc ++files[] = includes/phone.my.inc ++files[] = includes/phone.ph.inc ++files[] = includes/phone.us.inc ++files[] = tests/cck_phone.crud.test ++files[] = tests/cck_phone.crud_input.test ++files[] = tests/phone.gb.test ++files[] = tests/phone.my.test ++files[] = tests/phone.us.test +\ No newline at end of file +Index: cck_phone.install +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.install,v +retrieving revision 1.1 +diff -u -r1.1 cck_phone.install +--- cck_phone.install 8 Jul 2010 11:20:27 -0000 1.1 ++++ cck_phone.install 23 Jul 2010 11:58:48 -0000 +@@ -7,13 +7,12 @@ + * Installation file + */ + +- ++ + /** +- * Implementation of hook_install(). +- */ ++* Implementation of hook_install(). ++*/ + function cck_phone_install() { +- drupal_load('module', 'content'); +- content_notify('install', 'cck_phone'); ++ _cck_phone_update_country_code_list(); + drupal_set_message(st('Phone number module installed successfully.')); + } + +@@ -21,27 +20,51 @@ + * Implementation of hook_uninstall(). + */ + function cck_phone_uninstall() { +- drupal_load('module', 'content'); +- content_notify('uninstall', 'cck_phone'); ++ variable_del('cck_phone_custom_cc'); + } + + /** + * Implementation of hook_enable(). +- * +- * Notify content module when this module is enabled. + */ + function cck_phone_enable() { + // TODO: Migration path for phone.module to cck_phone +- drupal_load('module', 'content'); +- content_notify('enable', 'cck_phone'); + } + + /** + * Implementation of hook_disable(). +- * +- * Notify content module when this module is disabled. + */ + function cck_phone_disable() { +- drupal_load('module', 'content'); +- content_notify('disable', 'cck_phone'); ++ ++} ++ ++/** ++ * Update list of country codes phone validation. ++ */ ++function cck_phone_update_7000() { ++ _cck_phone_update_country_code_list(); + } ++ ++/** ++ * Store country code phone validation. ++ * ++ * This function should be called only at hook_update_N() ++ * when new country phone library is added. ++ */ ++function _cck_phone_update_country_code_list() { ++ // This function is too expensive to call at hook_init() and ++ // should be called only if there's a new country code added. ++ ++ // Load custom country codes phone number includes ++ $path = drupal_get_path('module', 'cck_phone') .'/includes'; ++ // Scan include phone numbers directory ++ $files = file_scan_directory($path, '/^phone\..*\.inc$/'); ++ ++ $countrycodes = array(); ++ foreach ($files as $file) { ++ list ($dummy, $countrycode) = explode('.', $file->name); ++ // Faster using array key ++ $countrycodes[$countrycode] = $countrycode; ++ } ++ // Save the list of country codes phone validation ++ variable_set('cck_phone_custom_cc', $countrycodes); ++} +\ No newline at end of file +Index: cck_phone.module +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.module,v +retrieving revision 1.3 +diff -u -r1.3 cck_phone.module +--- cck_phone.module 12 Jul 2010 09:54:52 -0000 1.3 ++++ cck_phone.module 26 Jul 2010 14:14:08 -0000 +@@ -3,341 +3,389 @@ + + /** + * @file +- * Defines phone number fields for CCK. ++ * Defines a field type for phone numbers. + * Provide some verifications on the phone numbers + */ + + define('CCK_PHONE_PHONE_MIN_LENGTH', 4); // Is there a phone number less than 4 digits? + define('CCK_PHONE_PHONE_MAX_LENGTH', 15); // International standard 15 digits + define('CCK_PHONE_EXTENSION_MAX_LENGTH', 6); +-define('CCK_PHONE_CC_MAX_LENGTH', 2); +-define('CCK_PHONE_MOBILE_AGENT', '/(ipod|iphone|android|blackberry|palm|nokia|opera\s+mobi|opera\s+mini|windows\s+ce|iemobile)/i'); ++define('CCK_PHONE_TEXTFIELD_MAX_LENGTH', 60); + + /** +- * Implementation of hook_init(). +- * This hook is called on module initialization. ++ * Implements hook_menu(). + */ +-function cck_phone_init() { +- // load country codes +- module_load_include('inc', 'cck_phone', 'cck_phone_countrycodes'); +- +- // load custom country codes phone number includes +- $path = drupal_get_path('module', 'cck_phone') .'/includes'; +- // scan include phone numbers directory +- $files = file_scan_directory($path, '^phone\..*\.inc$'); +- +- $countrycodes = array(); +- foreach ($files as $file) { +- module_load_include('inc', 'cck_phone', '/includes/'. $file->name); +- list ($dummy, $countrycode) = explode('.', $file->name); +- // faster using array key +- $countrycodes[$countrycode] = $countrycode; +- } ++function cck_phone_menu() { ++ $items['cck-phone/autocomplete/%'] = array( ++ 'page callback' => 'cck_phone_autocomplete', ++ 'access callback' => 'user_access', ++ 'access arguments' => array('access content'), ++ 'type' => MENU_CALLBACK, ++ ); ++ return $items; ++} + +- // save the list of country codes phone validation +- variable_set('cck_phone_custom_cc', $countrycodes); ++/** ++ * Menu callback; Retrieve a JSON object containing autocomplete suggestions ++ * for existing field content. ++ */ ++function cck_phone_autocomplete($string = '') { ++ $matches = array(); ++ if ($string) { ++ $field_name = arg(2); ++ $column_name = arg(3); ++ $column = $field_name . '_value'; ++ $field_table = 'field_data_' . $field_name; ++ $result = db_select($field_table)->fields($field_table, array($column))->condition($column, db_like($string) . '%', 'LIKE')->range(0, 10)->execute(); ++ foreach ($result as $field) { ++ $matches[$field->{$column}] = check_plain($field->{$column}); ++ } ++ } ++ drupal_json_output($matches); + } + + /** +- * Implementation of hook_theme(). ++ * Implementation of hook_field_info(). + */ +-function cck_phone_theme() { ++function cck_phone_field_info() { + return array( + 'phone_number' => array( +- 'arguments' => array('element' => NULL), +- ), +- 'phone_number_extension' => array( +- 'arguments' => array('extension' => ''), +- ), +- 'cck_phone_formatter_default' => array( +- 'arguments' => array('element' => NULL), +- ), +- 'cck_phone_formatter_local' => array( +- 'arguments' => array('element' => NULL), +- ), +- 'cck_phone_mobile_tel' => array( +- 'arguments' => array('element' => NULL, 'phone' => ''), ++ 'label' => t('Phone number'), ++ 'description' => t('Defines a field type for phone numbers.'), ++ 'settings' => array( ++ 'textfield_size' => CCK_PHONE_TEXTFIELD_MAX_LENGTH, ++ ), ++ 'instance_settings' => array( ++ 'default_country' => NULL, ++ 'all_country_codes' => TRUE, ++ 'phone_extra' => TRUE, ++ 'phone_as_link' => TRUE, ++ ), ++ 'default_widget' => 'phone_textfield', ++ 'default_formatter' => 'phone_formatter', + ), + ); + } + ++/** ++ * Implements hook_field_settings_form(). ++ */ ++function cck_phone_field_settings_form($field, $instance) { ++ $form = array(); ++ $defaults = field_info_field_settings($field['type']); ++ $settings = array_merge($defaults, $field['settings']); ++ $form['textfield_size'] = array( ++ '#type' => 'textfield', ++ '#title' => t('Size of textfield'), ++ '#default_value' => $settings['textfield_size'], ++ '#description' => t('Enter phone number textfield\'s width.'), ++ ); ++ return $form; ++} ++ ++/** ++ * Implements hook_field_instance_settings_form(). ++ */ ++function cck_phone_field_instance_settings_form($field, $instance) { ++ drupal_add_css(drupal_get_path('module', 'cck_phone') . '/css/cck_phone.css'); ++ drupal_add_js(drupal_get_path('module', 'cck_phone') . '/js/cck_phone.manage_field.js'); ++ $form = array(); ++ $defaults = field_info_instance_settings($field['type']); ++ $settings = array_merge($defaults, $instance['settings']); ++ $cc_options = _cck_phone_cc_options(TRUE); ++ $form['default_country'] = array( ++ '#type' => 'select', ++ '#title' => t('Default country code'), ++ '#default_value' => $settings['default_country'], ++ '#options' => $cc_options, ++ '#weight' => 1, ++ ); ++ $form['all_country_codes'] = array( ++ '#type' => 'checkbox', ++ '#title' => t('Show all country codes.'), ++ '#default_value' => $settings['all_country_codes'], ++ '#description' => t('Uncheck this to select the country to be displayed.'), ++ '#weight' => 1.1, ++ ); ++ // Country codes settings ++ $form['country_codes'] = array( ++ '#type' => 'fieldset', ++ '#title' => 'Country selection', ++ '#attributes' => array('class' => array('cck-phone-settings')), ++ '#collapsible' => TRUE, ++ '#collapsed' => TRUE, ++ '#weight' => 2, ++ '#description' => t('Country marks with * has custom country code settings and/or validation.'), ++ ); ++ $form['country_codes']['country_selection'] = array( ++ '#type' => 'checkboxes', ++ '#title' => t('Select country codes to be included'), ++ '#default_value' => isset($instance['settings']['country_codes']['country_selection']) && !empty($instance['settings']['country_codes']['country_selection']) ? $instance['settings']['country_codes']['country_selection'] : array($instance['settings']['default_country'] => $instance['settings']['default_country']), ++ '#options' => $cc_options, ++ ); ++ $form['phone_extra'] = array( ++ '#type' => 'checkbox', ++ '#default_value' => $settings['phone_extra'], ++ '#title' => t('Add extra phone number\'s description'), ++ '#weight' => 3, ++ ); ++ // We don't need to detect if the device is mobile. RDFA FOAF states: ++ // A phone, specified using fully qualified tel: URI scheme ++ // (http://xmlns.com/foaf/spec/#term_phone) ++ $form['phone_as_link'] = array( ++ '#type' => 'checkbox', ++ '#title' => t('Display phone number as link. !foaf: A phone, specified using fully qualified tel: URI scheme', array('!foaf' => l('RDFA FOAF', 'http://xmlns.com/foaf/spec/#term_phone'))), ++ '#default_value' => $settings['phone_as_link'], ++ '#weight' => 3, ++ ); ++ return $form; ++} + + /** +- * Implementation of hook_field_info(). ++ * Implements hook_field_schema(). + */ +-function cck_phone_field_info() { ++function cck_phone_field_schema($field) { + return array( +- 'phone_number' => array( +- 'label' => t('Phone number'), +- 'description' => t('Store a number and country code in the database to assemble a phone number.'), ++ 'columns' => array( ++ 'country' => array( ++ 'type' => 'varchar', ++ 'length' => 2, ++ 'not null' => TRUE, ++ 'description' => t('ISO 3166 2-character country code.'), ++ ), ++ 'int_code' => array( ++ 'type' => 'int', ++ 'not null' => TRUE, ++ 'description' => t('International country calling code.'), ++ ), ++ 'value' => array( ++ 'type' => 'varchar', ++ 'length' => CCK_PHONE_PHONE_MAX_LENGTH, ++ 'not null' => TRUE, ++ 'description' => t('Sanitized phone number with area code.'), ++ ), ++ 'extra' => array( ++ 'type' => 'varchar', ++ 'length' => 255, ++ 'not null' => FALSE, ++ 'description' => t('Extra phone number\'s description.'), ++ ), ++ 'type' => array( ++ 'type' => 'varchar', ++ 'length' => 16, ++ 'not null' => TRUE, ++ 'description' => t('hCard microformat property indicating the nature of the phone (voice, home, msg, work, pref, fax, cell, video, pager, bbs, modem, car, isdn, pcs).'), ++ ), ++ 'hidden' => array( ++ 'type' => 'char', ++ 'default' => 0, ++ 'not null' => FALSE, ++ 'description' => t('Boolean indicating weather the type is hidden or not.'), ++ ), ++ ++ ), ++ 'indexes' => array( ++ 'value_index' => array('value'), + ), + ); + } + + /** +- * Implementation of hook_field_settings(). ++ * Implements hook_field_validate(). + */ +-function cck_phone_field_settings($op, $field) { +- switch ($op) { +- case 'form': +- drupal_add_css(drupal_get_path('module', 'cck_phone') . '/cck_phone.css'); +- drupal_add_js(drupal_get_path('module', 'cck_phone') . '/cck_phone.js'); +- +- $form = array(); +- $form['default_country'] = array( +- '#type' => 'select', +- '#title' => t('Default country code'), +- '#default_value' => isset($field['default_country']) && ($field['default_country'] !== '') ? $field['default_country'] : NULL, +- '#options' => _cck_phone_cc_options(TRUE), +- ); +- +- $form['all_country_codes'] = array( +- '#type' => 'checkbox', +- '#title' => t('Show all country codes.'), +- '#default_value' => isset($field['all_country_codes']) && ($field['all_country_codes'] !== '') ? $field['all_country_codes'] : TRUE, +- '#description' => t('Uncheck this to select the country to be displayed.'), +- ); +- +- // Country codes settings +- $form['country_codes'] = array( +- '#title' => 'Country selection', +- '#type' => 'fieldset', +- '#collapsible' => TRUE, +- '#collapsed' => TRUE, +- '#attributes' => array('class' => 'cck-phone-settings'), +- ); +- +- $form['country_codes']['country_selection'] = array( +- '#type' => 'checkboxes', +- '#title' => t('Select country codes to be included'), +- '#default_value' => isset($field['country_selection']) && !empty($field['country_selection']) ? $field['country_selection'] : array($field['default_country'] => $field['default_country']), +- '#options' => _cck_phone_cc_options(TRUE), +- '#description' => t('Country marks with * has custom country code settings and/or validation.'), +- ); +- +- $form['enable_custom_country'] = array( +- '#type' => 'checkbox', +- '#title' => t('Enable country level validation'), +- '#default_value' => isset($field['enable_custom_country']) && ($field['enable_custom_country'] !== '') ? $field['enable_custom_country'] : TRUE, +- '#description' => t('Uncheck this to disable stringent country phone number validation.'), +- ); +- +- $form['enable_extension'] = array( +- '#type' => 'checkbox', +- '#title' => t('Enable phone extension support'), +- '#default_value' => isset($field['enable_extension']) && ($field['enable_extension'] !== '') ? $field['enable_extension'] : FALSE, +- '#description' => t('Check this to enable phone number extension field.'), +- ); +- +- $form['enable_mobile'] = array( +- '#type' => 'checkbox', +- '#title' => t('Enable mobile device detection'), +- '#default_value' => isset($field['enable_mobile']) && ($field['enable_mobile'] !== '') ? $field['enable_mobile'] : FALSE, +- '#description' => t('Check this to enable phone number link on mobile browsers (RFC3966).'), +- ); +- +- // Display country specific settings +- foreach (_cck_phone_custom_cc() as $cc) { +- $function = $cc . '_phone_field_settings'; +- if (function_exists($function)) { +- $country_settings = $function($op, $field); +- if (isset($country_settings) && !empty($country_settings)) { +- $country_codes = cck_phone_countrycodes($cc); +- // Wrap with fieldset +- $wrapper = array( +- '#title' => $country_codes['country'] . ' specific settings', +- '#type' => 'fieldset', +- '#collapsible' => TRUE, +- '#collapsed' => TRUE, +- '#attributes' => array('class' => 'cck-phone-settings cck-phone-settings-' . $cc), ++function cck_phone_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { ++ $field_name = $field['field_name']; ++ foreach ($items as $delta => $item) { ++ $phone_value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); ++ if (!empty($phone_value)) { ++ $subaddress_value = check_plain($item['subaddress_value']); ++ // Lenient checking, as long as it doesn't have invalid phone number characters ++ $regex = '/^ ++ [+\s.()-]* # optional separator ++ (?: # } ++ \d # } 4-15 digits number ++ [\s.()-]* # } each followed by optional separator ++ ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } ++ $/x'; ++ // Generic number validation ++ if (!preg_match($regex, $phone_value)) { ++ $errors[$field_name][$langcode][$delta][] = array( ++ 'error' => 'value', ++ 'message' => t('Phone number must be numeric and %min_length to %max_length length.', array('%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH)), ++ ); ++ } ++ else { ++ $code = $item['country']; ++ // Custom country level validation ++ $validate_function = $code . '_validate_number'; ++ $has_cc = module_load_include('inc', 'cck_phone', 'includes/phone.' . $code) && function_exists($validate_function); ++ if ($has_cc) { ++ if (!$validate_function($phone_value, '', $error_message)) { ++ $errors[$field_name][$langcode][$delta][] = array( ++ 'error' => 'value', ++ 'message' => $error_message, + ); +- $wrapper[] = $country_settings; +- array_push($form, $wrapper); + } + } + } +- +- return $form; +- +- case 'validate': +- // Validate country specific settings +- foreach (_cck_phone_custom_cc() as $cc) { +- $function = $cc . '_phone_field_settings'; +- if (function_exists($function)) { +- $function($op, $field); +- } +- } +- break; +- +- case 'save': +- $settings = array('default_country', 'all_country_codes', 'country_selection', 'enable_custom_country', 'enable_extension', 'enable_mobile'); +- +- // Save country specific settings +- foreach (_cck_phone_custom_cc() as $cc) { +- $function = $cc . '_phone_field_settings'; +- if (function_exists($function)) { +- array_push($settings, $function($op, $field)); +- } +- } +- return $settings; +- +- // TODO: filters for phone number? +-// case 'filters': +-// break; +- +- case 'database columns': +- return array( +- 'number' => array( +- 'type' => 'varchar', +- 'length' => CCK_PHONE_PHONE_MAX_LENGTH, +- 'not null' => FALSE, +- ), +- 'country_codes' => array( +- 'type' => 'varchar', +- 'length' => CCK_PHONE_CC_MAX_LENGTH, +- 'not null' => FALSE, +- ), +- 'extension' => array( +- 'type' => 'varchar', +- 'length' => CCK_PHONE_EXTENSION_MAX_LENGTH, +- 'not null' => FALSE, +- ), +- ); ++ } + } + } + + /** +- * Implementation of hook_field(). ++ * Implements hook_field_widget_error(). + */ +-function cck_phone_field($op, &$node, $field, &$items, $teaser, $page) { +- switch ($op) { +- case 'validate': +- foreach ($items as $delta => $value) { +- _cck_phone_validate($items[$delta], $delta, $field, $node); +- } +- +- return $items; +- break; +- +- case 'presave': +- foreach ($items as $delta => $value) { +- _cck_phone_process($items[$delta], $delta, $field, $node); +- } +- break; +- +- // Do country level code need to modify the output? +- case 'sanitize': +- foreach ($items as $delta => $value) { +- _cck_phone_sanitize($items[$delta], $delta, $field, $node); +- } +- break; ++function cck_phone_field_widget_error($element, $error, $form, &$form_state) { ++ $element['#parents'][] = $error['error']; ++ form_error($element, $error['message'], $form, $form_state); ++} + ++/** ++ * Implements hook_field_presave(). ++ */ ++function cck_phone_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { ++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); ++ $list = cck_phone_countrycodes(); ++ foreach ($items as $delta => $item) { ++ $code = $item['country']; ++ $value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); ++ $sanitize_number_function = $code . '_sanitize_number'; ++ if (function_exists($sanitize_number_function)) { ++ $sanitize_number_function($value); ++ } ++ $items[$delta]['value'] = $value; ++ $items[$delta]['int_code'] = (int) preg_replace('/^\+/', '', $list[$code]['code']); ++ $items[$delta]['extra'] = t($items[$delta]['extra']); ++ $items[$delta]['type'] = t($items[$delta]['type']); ++ $items[$delta]['hidden'] = (bool) $items[$delta]['hidden']; + } ++} + ++/** ++ * Implements hook_field_is_empty(). ++ */ ++function cck_phone_field_is_empty($item, $field) { ++ return empty($item['value']); + } + ++/************************************************************************** ++ * Field Type API: Widget ++ * ++ * The widget is the form element used to receive input from the user ++ * when the field is being populated. ++ **************************************************************************/ + /** +- * Implementation of hook_field_formatter_info(). ++ * Implement hook_field_widget_info(). + */ +-function cck_phone_field_formatter_info() { ++function cck_phone_field_widget_info() { + return array( +- 'default' => array( +- 'label' => 'Global phone number (default)', ++ 'phone_textfield' => array( ++ 'label' => t('Textfield'), + 'field types' => array('phone_number'), +- 'multiple values' => CONTENT_HANDLE_CORE, + ), +- 'local' => array( +- 'label' => 'Local phone number', ++ 'phone_autocomplete' => array( ++ 'label' => t('Autocomplete'), + 'field types' => array('phone_number'), +- 'multiple values' => CONTENT_HANDLE_CORE, +- ), ++ ), + ); + } + + /** +- * Theme function for phone extension. ++ * Implements hook_field_widget_form(). + */ +-function theme_phone_number_extension($extension = '') { +- return t(' ext. @extension', array('@extension' => $extension)); ++function cck_phone_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { ++ $field_name = $field['field_name']; ++ $elements = array(); ++ $elements['phone_field'] = $element; ++ $elements['phone_field']['#type'] = 'item'; ++ $elements['phone_field']['value'] = array( ++ '#type' => 'textfield', ++ '#size' => $field['settings']['textfield_size'] ? $field['settings']['textfield_size'] : CCK_PHONE_TEXTFIELD_MAX_LENGTH, ++ '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, ++ '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '', ++ '#parents' => array($field_name, $langcode, $delta, 'value'), ++ ); ++ if ($instance['widget']['type'] == 'phone_autocomplete') { ++ $elements['phone_field']['value']['#autocomplete_path'] = 'cck-phone/autocomplete/' . $field_name; ++ } ++ $elements['phone_field']['phone_advance'] = array( ++ '#type' => 'fieldset', ++ '#title' => t('Phone number options'), ++ '#collapsible' => TRUE, ++ '#collapsed' => TRUE, ++ ); ++ $elements['phone_field']['phone_advance']['country'] = array( ++ '#type' => 'select', ++ '#title' => t('Country code'), ++ '#default_value' => isset($items[$delta]['country']) ? $items[$delta]['country'] : $instance['settings']['default_country'], ++ '#parents' => array($field_name, $langcode, $delta, 'country'), ++ ); ++ if ($instance['settings']['all_country_codes']) { ++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(); ++ } ++ else { ++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(FALSE, $instance['settings']['country_codes']['country_selection']); ++ } ++ return $elements; + } + ++/*********************************************************************** ++ * Field Type API: Formatter ++ * ++ * These are the api hooks that present formatted (themed) output to the ++ * user. ++ **********************************************************************/ + /** +- * Theme function for mobile tel. ++ *Implementation of hook_field_formatter_info(). + */ +-function theme_cck_phone_mobile_tel($element, $phone = '') { +- $item = $element['#item']; +- +- // Mobile browsers support +- if (isset($item['mobile_output']) && $item['mobile_output'] == TRUE) { +- // Always output as global phone number without separator, leave the $phone display unchanged +- $cc = cck_phone_countrycodes($item['country_codes']); +- $tel = $cc['code'] . $item['number']; +- +- $phone = '' . $phone . ''; +- } +- +- return $phone; ++function cck_phone_field_formatter_info() { ++ return array( ++ 'phone_formatter' => array( ++ 'label' => t('Phone number'), ++ 'field types' => array('phone_number'), ++ ), ++ ); + } + + /** +- * Theme function for 'default' or global phone number field formatter. ++ * Implements hook_field_formatter_view(). + */ +-function theme_cck_phone_formatter_default($element) { +- $item = $element['#item']; +- $phone = ''; +- +- // Display a global phone number with country code. +- if (!empty($item['number']) && !empty($item['country_codes'])) { +- // Call country default formatter if exist +- $function = $item['country_codes'] . '_formatter_default'; +- if (function_exists($function)) { +- $phone = $function($element); ++function cck_phone_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) { ++ $element = array(); ++ $type_class = array('type'); ++ foreach ($items as $delta => $item) { ++ $code = $item['country']; ++ $int_code = $item['int_code']; ++ $tel_value = '+' . $item['int_code'] . $item['value']; ++ $formatter_default_function = $code . '_formatter_default'; ++ module_load_include('inc', 'cck_phone', 'includes/phone.' . $code); ++ if (function_exists($formatter_default_function)) { ++ $format = $formatter_default_function($item['value']); + } + else { +- $cc = cck_phone_countrycodes($item['country_codes']); +- $phone = $cc['code'] .'-'. $item['number']; +- } +- +- // Extension +- if (!empty($item['extension'])) { +- $phone = $phone . theme('phone_number_extension', $item['extension']); ++ $format = $item['value']; + } +- +- // Mobile browsers support +- $phone = theme('cck_phone_mobile_tel', $element, $phone); ++ $details = array( ++ 'value' => $format, ++ 'int_code' => $int_code, ++ 'tel_value' => $tel_value, ++ ); ++ $element[$delta]['#markup'] = theme('phone_field_view', array('phone' => $details)); + } +- +- return $phone; ++ return $element; + } + + /** +- * Theme function for 'local' phone number field formatter. ++ * Implementation of hook_theme() + */ +-function theme_cck_phone_formatter_local($element) { +- $item = $element['#item']; +- $phone = ''; +- +- // Display a local phone number without country code. +- if (!empty($item['number'])) { +- // Call country local formatter if exist +- $function = $item['country_codes'] . '_formatter_local'; +- if (function_exists($function)) { +- $phone = $function($element); +- } +- else { +- $phone = $item['number']; +- } +- +- // Extension +- if (!empty($item['extension'])) { +- $phone = $phone . theme('phone_number_extension', $item['extension']); +- } +- +- // Mobile browsers support +- $phone = theme('cck_phone_mobile_tel', $element, $phone); +- } +- +- return $phone; ++function cck_phone_theme($existing, $type, $theme, $path) { ++ return array( ++ 'phone_field_view' => array( ++ 'render element' => 'phone', ++ 'template' => 'phone-field-view', ++ 'path' => drupal_get_path('module', 'cck_phone') . '/theme', ++ ), ++ ); + } + + /** +@@ -350,16 +398,19 @@ + * @return string + */ + function _cck_phone_cc_options($show_custom = FALSE, $country_selection = array()) { ++ // Load country codes ++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); ++ + $options = array(); +- + if ($show_custom) { + $custom_cc = _cck_phone_custom_cc(); + } +- +- foreach (cck_phone_countrycodes() as $cc => $value) { ++ ++ $list = cck_phone_countrycodes(); ++ foreach ($list as $cc => $value) { + $cc_name = $value['country'] .' ('. $value['code'] .')'; + +- // faster using array key instead of in_array ++ // Faster using array key instead of in_array + if ($show_custom && isset($custom_cc[$cc])) { + $cc_name .= ' *'; + } +@@ -380,401 +431,9 @@ + * Array of country codes abbreviation or FALSE if none exist. + */ + function _cck_phone_custom_cc() { +- static $cc; +- ++ $cc = &drupal_static(__FUNCTION__); + if (!isset($cc)) { + $cc = variable_get('cck_phone_custom_cc', FALSE); + } +- + return $cc; +-} +- +-function _cck_phone_valid_input($input) { +- // lenient checking, as long as don't have invalid phone number character +- $regex = '/^ +- [\s.()-]* # optional separator +- (?: # } +- \d # } 4-15 digits number +- [\s.()-]* # } each followed by optional separator +- ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } +- $/x'; +- +- return preg_match($regex, $input); +-} +- +-function _cck_phone_valid_cc_input($list, $cc) { +- if (isset($list[$cc]) && $list[$cc] == $cc) { +- return TRUE; +- } +- +- return FALSE; +-} +- +-function _cck_phone_validate(&$item, $delta, $field, $node) { +- $phone_input = trim($item['number']); +- $countrycode = trim($item['country_codes']); +- $ext_input = ''; +- if ($field['enable_extension']) { +- $ext_input = trim($item['extension']); +- } +- +- if ($phone_input && !(isset($field['widget']['default_value'][$delta]['number']) && $phone_input == $field['widget']['default_value'][$delta]['number'] && !$field['required'])) { +- +- $error_params = array( +- '%phone_input' => check_plain($phone_input), // original phone input +- '%countrycode' => check_plain($countrycode), +- '%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, +- '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH, +- '%ext_input' => check_plain($ext_input), +- '%ext_max_length' => CCK_PHONE_EXTENSION_MAX_LENGTH, +- ); +- +- // Only allow digit, dash, space and bracket +- if (!_cck_phone_valid_input($phone_input, $ext_input)) { +- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); +- if ($field['enable_extension'] && $ext_input != '') { +- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); +- } +- +- form_set_error($field['field_name'], $error); +- } +- else { +- if (!$field['all_country_codes']) { +- if (!_cck_phone_valid_cc_input($field['country_selection'], $countrycode)) { +- $error = t('Invalid country code "%countrycode" submitted.', $error_params); +- form_set_error($field['field_name'], $error); +- } +- } +- // Generic number validation +- if (!cck_phone_validate_number($countrycode, $phone_input, $ext_input)) { +- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); +- if ($field['enable_extension'] && $ext_input != '') { +- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); +- } +- +- form_set_error($field['field_name'], $error); +- } +- // Country level validation if enabled +- elseif ($field['enable_custom_country'] != 0 || is_null($field['enable_custom_country']) || !isset($field['enable_custom_country'])) { +- $custom_cc = _cck_phone_custom_cc(); +- +- if (isset($custom_cc[$countrycode])) { +- $validate_function = $countrycode . '_validate_number'; +- +- if (function_exists($validate_function)) { +- $error = ''; +- if (!$validate_function($phone_input, $ext_input, $error)) { +- form_set_error($field['field_name'], t($error, $error_params)); +- } +- } +- } +- } +- } +- } +-} +- +-function _cck_phone_process(&$item, $delta = 0, $field, $node) { +- $widget = $field['widget']['default_value'][$delta]; +- // Clean up the phone number. +- $item['number'] = cck_phone_clean_number($item['number']); +- $item['extension'] = cck_phone_clean_number($item['extension']); +- +- // Don't save an invalid default value. +- if ((isset($widget['number']) && $item['number'] == $widget['number']) && (isset($widget['country_codes']) && $item['country_codes'] == $widget['country_codes']) && is_object($node)) { +- if (!cck_phone_validate_number($item['country_codes'], $item['number'], $item['extension'])) { +- unset($item['number']); +- unset($item['country_codes']); +- unset($item['extension']); +- } +- } +-} +- +-/** +- * Cleanup user-entered values for a phone number field according to field settings. +- * +- * @param $item +- * A single phone number item, usually containing number and country code. +- * @param $delta +- * The delta value if this field is one of multiple fields. +- * @param $field +- * The CCK field definition. +- * @param $node +- * The node containing this phone number. +- */ +-function _cck_phone_sanitize(&$item, $delta, &$field, &$node) { +- if (!empty($item['number'])) { +- $cc = $item['country_codes']; +- $item['number'] = cck_phone_clean_number($item['number']); +- +- $custom_cc = _cck_phone_custom_cc(); +- if (isset($custom_cc[$cc])) { +- $function = $cc . '_sanitize_number'; +- +- if (function_exists($function)) { +- $function($item['number']); +- } +- } +- } +- +- if ($field['enable_extension']) { +- $item['extension'] = cck_phone_clean_number($item['extension']); +- } +- else { +- unset($item['extension']); +- } +- +- if ($field['enable_mobile'] && preg_match(CCK_PHONE_MOBILE_AGENT, drupal_strtolower($_SERVER['HTTP_USER_AGENT']))) { +- $item['mobile_output'] = TRUE; +- } +-} +- +- +-/** +- * Implementation of hook_widget_info(). +- */ +-function cck_phone_widget_info() { +- return array( +- 'phone_number' => array( +- 'label' => t('Phone number'), +- 'field types' => array('phone_number'), +- 'multiple values' => CONTENT_HANDLE_CORE, +- ), +- ); +-} +- +-/** +- * Implementation of hook_widget_settings(). +- */ +-function cck_phone_widget_settings($op, $widget) { +- switch ($op) { +- case 'form': +- $form = array(); +- $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : CCK_PHONE_PHONE_MAX_LENGTH; +- $form['input']['size'] = array( +- '#type' => 'textfield', +- '#title' => t('Size of phone number textfield'), +- '#default_value' => $size, +- '#element_validate' => array('_element_validate_integer_positive'), +- '#required' => TRUE, +- '#description' => t('International number is maximum 15 digits with additional country code, default is %length.', array('%length' => CCK_PHONE_PHONE_MAX_LENGTH)), +- ); +- return $form; +- +- case 'save': +- return array('size'); +- } +-} +- +-/** +- * Implementation of hook_widget(). +- */ +-function cck_phone_widget(&$form, &$form_state, $field, $items, $delta = 0) { +- $element = array( +- '#type' => $field['widget']['type'], +- '#default_value' => isset($items[$delta]) ? $items[$delta] : '', +- '#title' => $field['widget']['label'], +- '#weight' => $field['widget']['weight'], +- '#description' => $field['widget']['description'], +- '#required' => $field['required'], +- '#field' => $field, +- ); +- return $element; +-} +- +-/** +- * Implementation of hook_content_is_empty(). +- */ +-function cck_phone_content_is_empty($item, $field) { +- if (empty($item['number'])) { +- return TRUE; +- } +- return FALSE; +-} +- +-/** +- * Implementation of FAPI hook_elements(). +- */ +-function cck_phone_elements() { +- return array( +- 'phone_number' => array( +- '#input' => TRUE, +- '#process' => array('cck_phone_process'), +- '#autocomplete_path' => FALSE, +- ), +- ); +-} +- +-/** +- * FAPI theme for an individual phone number elements. +- * +- * The phone number is already rendered by the themes and the html +- * output lives in $element['#children']. Override this theme to +- * make custom changes to the output. +- * +- * $element['#title'] is the field title +- * $element['#field_name'] contains the field name +- * $element['#delta''] is the position of this element in the group +- * $element['number] is the phone number +- * $element['country_codes'] is the country code +- */ +-function theme_phone_number($element) { +- drupal_add_css(drupal_get_path('module', 'cck_phone') .'/cck_phone.css'); +- +- // Prefix single value phone number fields with the name of the field. +-// if (empty($element['#field']['multiple'])) { +-// if (isset($element['number']) && isset($element['country_codes'])) { +-// $element['number']['#title'] = $element['#title'] .' '. $element['number']['#title']; +-// $element['country_codes']['#title'] = $element['#title'] .' '. $element['country_codes']['#title']; +-// } +-// elseif ($element['number']) { +-// $element['number']['#title'] = $element['#title']; +-// } +-// } +- +- $output = ''; +- +- $output = '
*' : ''; +- +- if (!empty($element['#title'])) { +- $title = $element['#title']; +- if (!empty($element['number']['#id'])) { +- $output .= ' \n"; +- } +- else { +- $output .= ' \n"; +- } +- } +- +- $output .= '
'; +- if (isset($element['number'])) { +- $output .= '
'. theme('textfield', $element['number']) .'
'; +- } +- if (isset($element['extension'])) { +- $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : ''; +- $output .= '
'. $prefix . theme('textfield', $element['extension']) .'
'; +- } +- $output .= '
'. theme('select', $element['country_codes']) .'
'; +- $output .= '
'; +- +- return $output; +-} +- +-/** +- * Process an individual element. +- */ +-function cck_phone_process($element, $edit, $form_state, $form) { +- $field_name = $element['#field_name']; +- $field = $form['#field_info'][$field_name]; +- $field_key = $element['#columns'][0]; +- $delta = $element['#delta']; +- +- $element['number'] = array( +- '#type' => 'textfield', +- '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, +- '#size' => CCK_PHONE_PHONE_MAX_LENGTH, +-// '#title' => t('Number'), +- '#description' => $element['#description'], +- '#required' => ($delta == 0 && $field['number'] !== 'optional') ? $element['#required'] : FALSE, +- '#default_value' => isset($element['#value']['number']) ? $element['#value']['number'] : NULL, +- ); +- +- if ($field['enable_extension']) { +- $element['extension'] = array( +- '#type' => 'textfield', +- '#maxlength' => CCK_PHONE_EXTENSION_MAX_LENGTH, +- '#size' => CCK_PHONE_EXTENSION_MAX_LENGTH, +-// '#title' => t('ext'), +- '#required' => FALSE, +- '#default_value' => isset($element['#value']['extension']) ? $element['#value']['extension'] : NULL, +- '#prefix' => '
'. t('ext') .'
', +- ); +- } +- +- $element['country_codes'] = array( +- '#type' => 'select', +-// '#title' => 'Country code', +- '#default_value' => ($element['#value']['number'] != '' && isset($element['#value']['country_codes'])) ? $element['#value']['country_codes'] : (isset($field['default_country']) ? $field['default_country'] : NULL), +- ); +- if ($field['all_country_codes']) { +- $element['country_codes']['#options'] = _cck_phone_cc_options(); +- } +- else { +- $element['country_codes']['#options'] = _cck_phone_cc_options(FALSE, $field['country_selection']); +- } +- +- return $element; +-} +- +-/** +- * Strip number of space, hash, dash, bracket, etc leaving digit only. +- * +- * @param string $number +- * @return string Returns digit only phone number. +- */ +-function cck_phone_clean_number($number) { +- // Remove none numeric characters +- $number = preg_replace('/[^0-9]/', '', $number); +- +- return $number; +-} +- +-/** +- * Generic validation for Phone Number. +- * +- * @param string $countrycode +- * @param string $number +- * @return boolean Returns boolean FALSE if the phone number is not valid. +- */ +-function cck_phone_validate_number($countrycode, $number, $ext = '') { +- // We don't want to worry about separators +- $number = cck_phone_clean_number($number); +- if ($number !== '' && drupal_strlen($number) > CCK_PHONE_PHONE_MAX_LENGTH) { +- return FALSE; +- } +- +- $ext = cck_phone_clean_number($ext); +- if ($ext !== '' && drupal_strlen($ext) > CCK_PHONE_EXTENSION_MAX_LENGTH) { +- return FALSE; +- } +- +- return TRUE; +-} +- +- +-/* ------ Token ------ */ +- +-/** +- * Implementation of hook_token_list(). +- */ +-function cck_phone_token_list($type = 'all') { +- if ($type == 'field' || $type == 'all') { +- $tokens = array(); +- +- $tokens['cck_phone']['number'] = t('Phone number'); +- $tokens['cck_phone']['country_codes'] = t('Country code'); +- $tokens['cck_phone']['extension'] = t('Extension'); +- +- return $tokens; +- } +-} +- +-/** +- * Implementation of hook_token_values(). +- */ +-function cck_phone_token_values($type, $object = NULL, $options = array()) { +- if ($type == 'field') { +- $item = $object[0]; +- +- $tokens['number'] = $item['number']; +- $tokens['country_codes'] = $item['country_codes']; +- $tokens['cck_phone']['extension'] = $item['extension']; +- +- return $tokens; +- } +-} ++} +\ No newline at end of file +Index: includes/phone.ca.inc +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.ca.inc,v +retrieving revision 1.1 +diff -u -r1.1 phone.ca.inc +--- includes/phone.ca.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++ includes/phone.ca.inc 24 Jul 2010 06:02:20 -0000 +@@ -7,23 +7,25 @@ + */ + + /** +- * Verifies that $number is a valid ten-digit North American phone number. ++ * Validate country level phone number. + * + * @param $number +- * Digits only value. +- * @param $ext +- * Digits only value. ++ * Digits only phone number value. ++ * @param $subaddress ++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++ * Reference: http://tools.ietf.org/html/rfc2806. + * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number ++ * Error message that will be displayed to user. ++ * @param $phone_type ++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++ * Pager, BBS, Modem, Car, ISDN, PCS) + * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * TRUE if it is a valid phone number for this country, FALSE otherwise. + */ +-function ca_validate_number($number, $ext = '', &$error) { +- return us_validate_number($number, $ext = '', &$error); ++function ca_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); ++ return us_validate_number($number, $subaddress, $error, $phone_type); + } + + /** +@@ -33,43 +35,17 @@ + * A single phone number item. + */ + function ca_sanitize_number(&$number) { ++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); + us_sanitize_number($number); + } + + /** + * Default formatter for international phone number. + * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. +- */ +-function ca_formatter_default($element) { +- return us_formatter_default($element); +-} +- +-/** +- * Local formatter for local phone number. +- * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * @param $number ++ * Phone number. + */ +-function ca_formatter_local($element) { +- return us_formatter_local($element); ++function ca_formatter_default($number) { ++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); ++ return us_formatter_default($number); + } +\ No newline at end of file +Index: includes/phone.gb.inc +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.gb.inc,v +retrieving revision 1.1 +diff -u -r1.1 phone.gb.inc +--- includes/phone.gb.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++ includes/phone.gb.inc 24 Jul 2010 07:12:33 -0000 +@@ -25,29 +25,27 @@ + * Validate country level phone number. + * + * @param $number +- * Digits only value. +- * @param $ext +- * Digits only value. ++ * Digits only phone number value. ++ * @param $subaddress ++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++ * Reference: http://tools.ietf.org/html/rfc2806. + * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number ++ * Error message that will be displayed to user. ++ * @param $phone_type ++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++ * Pager, BBS, Modem, Car, ISDN, PCS) + * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * TRUE if it is a valid phone number for this country, FALSE otherwise. + */ +-function gb_validate_number($number, $ext = '', &$error) { +- // We don't want to worry about separators +- $number = cck_phone_clean_number($number); +- +- if (preg_match(_uk_phone_rules(), $number)) { +- return TRUE; ++function gb_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++ if (!empty($number)) { ++ if (preg_match(_uk_phone_rules(), $number)) { ++ return TRUE; ++ } ++ $error = t('"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "29 9999 9999", with optional leading "0"', array('%phone_input' => $number)); ++ return FALSE; + } +- +- // t() is no needed +- $error = '"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "99 9999 9999", with optional leading "0"'; +- return FALSE; + } + + /** +@@ -64,58 +62,16 @@ + /** + * Default formatter for international phone number. + * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. +- */ +-function gb_formatter_default($element) { +- $item = $element['#item']; +- +- // Display a global phone number with country code. +- $cc = cck_phone_countrycodes($item['country_codes']); +- +- $result = preg_match(_uk_phone_rules, $item['number'], $matches); +- +- if ($result) { +- // output as +44 AA BBBB CCCC, +44 AAA BBB CCCC or +44 AAAA BBB CCC +- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; +- } +- +- return $phone; +-} +- +- +-/** +- * Local formatter for local phone number. +- * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * @param $number ++ * Phone number. + */ +-function gb_formatter_local($element) { +- // Display a local phone number without country code. +- $result = preg_match(_uk_phone_rules, $item['number'], $matches); ++function gb_formatter_default($number) { ++ $result = preg_match(_uk_phone_rules(), $number, $matches); + + if ($result) { +- // output as 0AA BBBB CCCC, 0AAA BBB CCCC or 0AAAA BBB CCC +- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++ // output as AA BBBB CCCC, AAA BBB CCCC or AAAA BBB CCC ++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; + } + + return $phone; +-} ++} +\ No newline at end of file +Index: includes/phone.my.inc +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.my.inc,v +retrieving revision 1.1 +diff -u -r1.1 phone.my.inc +--- includes/phone.my.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++ includes/phone.my.inc 24 Jul 2010 07:08:18 -0000 +@@ -45,78 +45,64 @@ + } + + /** +- * Verifies that $number is a valid Malaysia phone number. ++ * Validate country level phone number. + * + * @param $number +- * Digits only value. +- * @param $ext +- * Digits only value. ++ * Digits only phone number value. ++ * @param $subaddress ++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++ * Reference: http://tools.ietf.org/html/rfc2806. + * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number ++ * Error message that will be displayed to user. ++ * @param $phone_type ++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++ * Pager, BBS, Modem, Car, ISDN, PCS) + * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * TRUE if it is a valid phone number for this country, FALSE otherwise. + */ +-function my_validate_number($number, $ext = '', &$error) { +- // We don't want to worry about separators +- $number = cck_phone_clean_number($number); +- +- foreach (_my_phone_rules() as $rule) { +- // define regular expression +- $regex = '/^ +- ([0]*) # an optional 0 +- ('. $rule[0] .') # area code +- \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] +- $/x'; +- +- $result = preg_match($regex, $number, $matches); +- +- if ($result) { +- return TRUE; ++function my_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++ if (!empty($number)) { ++ foreach (_my_phone_rules() as $rule) { ++ // define regular expression ++ $regex = '/^ ++ ([0]*) # an optional 0 ++ ('. $rule[0] .') # area code ++ \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] ++ $/x'; ++ ++ $result = preg_match($regex, $number, $matches); ++ ++ if ($result) { ++ return TRUE; ++ } + } ++ $error = t('"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.', array('%phone_input' => $number)); ++ return FALSE; + } +- +- // t() is no needed +- $error = '"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.'; +- return FALSE; + } + + /** +- * Cleanup user-entered values for a phone number field for saving to DB. ++ * Cleanup user-entered values for a phone number field for storing to DB. + * + * @param $number + * A single phone number item. ++ * @param $href ++ * Valid number (numeric and + charaters only) placed at ++ * href="tel:;ext=123" of anchor tag. + */ + function my_sanitize_number(&$number) { + // Remove trunk prefix '0' +- + $number = preg_replace('/^([0]*)/', '', $number); + } + + /** + * Default formatter for international phone number. + * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * @param $number ++ * Phone number. + */ +-function my_formatter_default($element) { +- $item = $element['#item']; +- +- // Display a global phone number with country code. +- $cc = cck_phone_countrycodes($item['country_codes']); +- ++function my_formatter_default($number) { + // Format the phone number however you like, this is the default + foreach (_my_phone_rules() as $rule) { + // define regular expression +@@ -125,55 +111,14 @@ + (\d{3,4}) + (\d{4}) + $/x'; +- +- $result = preg_match($regex, $item['number'], $matches); ++ $result = preg_match($regex, $number, $matches); + + if ($result) { +- // output as +60A-BBB CCCC or +60A-BBBB CCCC +- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++ // output as A-BBB CCCC ++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; + + continue; + } + } +- +- return $phone . $ext; +-} +- +-/** +- * Local formatter for local phone number. +- * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. +- */ +-function my_formatter_local($element) { +- // Display a local phone number without country code. +- $phone = $element['#item']['number']; +- +- foreach (_my_phone_rules() as $rule) { +- // define regular expression +- $regex = '/^ +- ('. $rule[0] .') # area code +- (\d{3,4}) +- (\d{4}) +- $/x'; +- +- $result = preg_match($regex, $phone, $matches); +- +- if ($result) { +- // output as 0A-BBB CCCC or 0A-BBBB CCCC +- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; +- continue; +- } +- } +- + return $phone; +-} ++} +\ No newline at end of file +Index: includes/phone.us.inc +=================================================================== +RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.us.inc,v +retrieving revision 1.1 +diff -u -r1.1 phone.us.inc +--- includes/phone.us.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++ includes/phone.us.inc 24 Jul 2010 06:51:51 -0000 +@@ -7,48 +7,45 @@ + */ + + /** +- * Verifies that $number is a valid ten-digit North American phone number. ++ * Validate country level phone number. + * + * @param $number +- * Digits only value. +- * @param $ext +- * Digits only value. ++ * Digits only phone number value. ++ * @param $subaddress ++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++ * Reference: http://tools.ietf.org/html/rfc2806. + * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number ++ * Error message that will be displayed to user. ++ * @param $phone_type ++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++ * Pager, BBS, Modem, Car, ISDN, PCS) + * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * TRUE if it is a valid phone number for this country, FALSE otherwise. + */ +-function us_validate_number($number, $ext = '', &$error) { +- // Don't need to check for extension because it has been checked by generic validation as all digits, unless has special format/requirements +- // We don't want to worry about separators +- $number = cck_phone_clean_number($number); +- +- // define regular expression +- $regex = '/^ +- ([1]*) # an optional 1 +- [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) +- [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) +- \d{4} # 4-digit line number +- $/x'; +- +- $result = preg_match($regex, $number, $matches); +- +- if ($result && $matches[1] == '') { +- return TRUE; +- } +- elseif ($result && $matches[1] == '1') { +- // t() is no needed +- $error = 'Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'; +- return FALSE; +- } +- else { +- // t() is no needed +- $error = '"%phone_input" is not a valid North American phone number, it should be 10 digits number like "999 999 9999"'; +- return FALSE; ++function us_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++ if (!empty($number)) { ++ // Define regular expression ++ $regex = '/^ ++ ([1]*) # an optional 1 ++ [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) ++ [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) ++ \d{4} # 4-digit line number ++ $/x'; ++ ++ $result = preg_match($regex, $number, $matches); ++ ++ if ($result && $matches[1] == '') { ++ return TRUE; ++ } ++ elseif ($result && $matches[1] == '1') { ++ $error = t('Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'); ++ return FALSE; ++ } ++ else { ++ $error = t('%phone_input is not a valid North American phone number, it should be 10 digits number like "989 999 9999"', array('%phone_input' => $number)); ++ return FALSE; ++ } + } + } + +@@ -68,25 +65,10 @@ + /** + * Default formatter for international phone number. + * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++ * @param $number ++ * Phone number. + */ +-function us_formatter_default($element) { +- $item = $element['#item']; +- $phone = ''; +- +- // Display a global phone number with country code. +- $cc = cck_phone_countrycodes($item['country_codes']); +- ++function us_formatter_default($number) { + // Format the phone number however you like, this is the default + // define regular expression + $regex = '/^ +@@ -95,43 +77,7 @@ + (\d{4}) # 4-digit line number + /x'; + +- $result = preg_match($regex, $item['number'], $matches); +- +- if ($result) { +- // output as +1 (AAA) BBB CCCC +- $phone = $cc['code'] .' ('. $matches[1] .') '. $matches[2] .' '. $matches[3]; +- } +- +- return $phone . $ext; +-} +- +-/** +- * Local formatter for local phone number. +- * +- * @param $element +- * $element['#item']['country_codes']: alpha-2 country code +- * $element['#item']['number']: phone number +- * @param $error +- * The error message to shown to user. +- * Available parameters to use in the error message are +- * - "%countrycode": the alpha-2 CC +- * - "%phone_input": the original number input by user (could be invalid) +- * - "%max_length": allowed maximum length of the phone number +- * @return boolean +- * TRUE if it is a valid phone number for that country, FALSE otherwise. +- */ +-function us_formatter_local($element) { +- $item = $element['#item']; +- $phone = ''; +- +- // Display a local phone number without country code. +- $regex = '/^ +- ([2-9][0-8]\d) # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) +- ([2-9]\d{2}) # 3-digit prefix (cannot start with 0 or 1) +- (\d{4}) # 4-digit line number +- /x'; +- +- $result = preg_match($regex, $item['number'], $matches); ++ $result = preg_match($regex, $number, $matches); + + if ($result) { + // output as (AAA) BBB CCCC +@@ -139,4 +85,4 @@ + } + + return $phone; +-} ++} +\ No newline at end of file +--- cck_phone autocomplete.patch ++++ cck_phone autocomplete.patch +@@ -0,0 +1,5284 @@ ++Index: cck_phone.info ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.info,v ++retrieving revision 1.1 ++diff -u -r1.1 cck_phone.info ++--- cck_phone.info 8 Jul 2010 11:20:27 -0000 1.1 +++++ cck_phone.info 22 Jul 2010 13:11:15 -0000 ++@@ -1,7 +1,18 @@ ++ ; $Id: cck_phone.info,v 1.1 2010/07/08 11:20:27 ckng Exp $ ++-name = Phone Number ++-description = "The phone module allows administrators to define a CCK field type for phone numbers." +++name = Phone number +++description = Defines a field type for phone number. ++ package = CCK ++-dependencies[] = content ++-core = 6.x ++- +++core = 7.x +++files[] = cck_phone.module +++files[] = theme/phone-field-view.tpl.php +++files[] = includes/cck_phone_countrycodes.inc +++files[] = includes/phone.ca.inc +++files[] = includes/phone.gb.inc +++files[] = includes/phone.my.inc +++files[] = includes/phone.ph.inc +++files[] = includes/phone.us.inc +++files[] = tests/cck_phone.crud.test +++files[] = tests/cck_phone.crud_input.test +++files[] = tests/phone.gb.test +++files[] = tests/phone.my.test +++files[] = tests/phone.us.test ++\ No newline at end of file ++Index: cck_phone.install ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.install,v ++retrieving revision 1.1 ++diff -u -r1.1 cck_phone.install ++--- cck_phone.install 8 Jul 2010 11:20:27 -0000 1.1 +++++ cck_phone.install 23 Jul 2010 11:58:48 -0000 ++@@ -7,13 +7,12 @@ ++ * Installation file ++ */ ++ ++- +++ ++ /** ++- * Implementation of hook_install(). ++- */ +++* Implementation of hook_install(). +++*/ ++ function cck_phone_install() { ++- drupal_load('module', 'content'); ++- content_notify('install', 'cck_phone'); +++ _cck_phone_update_country_code_list(); ++ drupal_set_message(st('Phone number module installed successfully.')); ++ } ++ ++@@ -21,27 +20,51 @@ ++ * Implementation of hook_uninstall(). ++ */ ++ function cck_phone_uninstall() { ++- drupal_load('module', 'content'); ++- content_notify('uninstall', 'cck_phone'); +++ variable_del('cck_phone_custom_cc'); ++ } ++ ++ /** ++ * Implementation of hook_enable(). ++- * ++- * Notify content module when this module is enabled. ++ */ ++ function cck_phone_enable() { ++ // TODO: Migration path for phone.module to cck_phone ++- drupal_load('module', 'content'); ++- content_notify('enable', 'cck_phone'); ++ } ++ ++ /** ++ * Implementation of hook_disable(). ++- * ++- * Notify content module when this module is disabled. ++ */ ++ function cck_phone_disable() { ++- drupal_load('module', 'content'); ++- content_notify('disable', 'cck_phone'); +++ +++} +++ +++/** +++ * Update list of country codes phone validation. +++ */ +++function cck_phone_update_7000() { +++ _cck_phone_update_country_code_list(); ++ } +++ +++/** +++ * Store country code phone validation. +++ * +++ * This function should be called only at hook_update_N() +++ * when new country phone library is added. +++ */ +++function _cck_phone_update_country_code_list() { +++ // This function is too expensive to call at hook_init() and +++ // should be called only if there's a new country code added. +++ +++ // Load custom country codes phone number includes +++ $path = drupal_get_path('module', 'cck_phone') .'/includes'; +++ // Scan include phone numbers directory +++ $files = file_scan_directory($path, '/^phone\..*\.inc$/'); +++ +++ $countrycodes = array(); +++ foreach ($files as $file) { +++ list ($dummy, $countrycode) = explode('.', $file->name); +++ // Faster using array key +++ $countrycodes[$countrycode] = $countrycode; +++ } +++ // Save the list of country codes phone validation +++ variable_set('cck_phone_custom_cc', $countrycodes); +++} ++\ No newline at end of file ++Index: cck_phone.module ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.module,v ++retrieving revision 1.3 ++diff -u -r1.3 cck_phone.module ++--- cck_phone.module 12 Jul 2010 09:54:52 -0000 1.3 +++++ cck_phone.module 26 Jul 2010 14:03:44 -0000 ++@@ -3,341 +3,356 @@ ++ ++ /** ++ * @file ++- * Defines phone number fields for CCK. +++ * Defines a field type for phone numbers. ++ * Provide some verifications on the phone numbers ++ */ ++ ++ define('CCK_PHONE_PHONE_MIN_LENGTH', 4); // Is there a phone number less than 4 digits? ++ define('CCK_PHONE_PHONE_MAX_LENGTH', 15); // International standard 15 digits ++ define('CCK_PHONE_EXTENSION_MAX_LENGTH', 6); ++-define('CCK_PHONE_CC_MAX_LENGTH', 2); ++-define('CCK_PHONE_MOBILE_AGENT', '/(ipod|iphone|android|blackberry|palm|nokia|opera\s+mobi|opera\s+mini|windows\s+ce|iemobile)/i'); +++define('CCK_PHONE_TEXTFIELD_MAX_LENGTH', 60); ++ ++ /** ++- * Implementation of hook_init(). ++- * This hook is called on module initialization. +++ * Implements hook_menu(). ++ */ ++-function cck_phone_init() { ++- // load country codes ++- module_load_include('inc', 'cck_phone', 'cck_phone_countrycodes'); ++- ++- // load custom country codes phone number includes ++- $path = drupal_get_path('module', 'cck_phone') .'/includes'; ++- // scan include phone numbers directory ++- $files = file_scan_directory($path, '^phone\..*\.inc$'); ++- ++- $countrycodes = array(); ++- foreach ($files as $file) { ++- module_load_include('inc', 'cck_phone', '/includes/'. $file->name); ++- list ($dummy, $countrycode) = explode('.', $file->name); ++- // faster using array key ++- $countrycodes[$countrycode] = $countrycode; ++- } +++function cck_phone_menu() { +++ $items['cck-phone/autocomplete/%'] = array( +++ 'page callback' => 'cck_phone_autocomplete', +++ 'access callback' => 'user_access', +++ 'access arguments' => array('access content'), +++ 'type' => MENU_CALLBACK, +++ ); +++ return $items; +++} ++ ++- // save the list of country codes phone validation ++- variable_set('cck_phone_custom_cc', $countrycodes); +++/** +++ * Menu callback; Retrieve a JSON object containing autocomplete suggestions +++ * for existing field content. +++ */ +++function cck_phone_autocomplete($string = '') { +++ $matches = array(); +++ if ($string) { +++ $field_name = arg(2); +++ $column_name = arg(3); +++ $column = $field_name . '_value'; +++ $field_table = 'field_data_' . $field_name; +++ $result = db_select($field_table)->fields($field_table, array($column))->condition($column, db_like($string) . '%', 'LIKE')->range(0, 10)->execute(); +++ foreach ($result as $field) { +++ $matches[$field->{$column}] = check_plain($field->{$column}); +++ } +++ } +++ drupal_json_output($matches); ++ } ++ ++ /** ++- * Implementation of hook_theme(). +++ * Implementation of hook_field_info(). ++ */ ++-function cck_phone_theme() { +++function cck_phone_field_info() { ++ return array( ++ 'phone_number' => array( ++- 'arguments' => array('element' => NULL), ++- ), ++- 'phone_number_extension' => array( ++- 'arguments' => array('extension' => ''), ++- ), ++- 'cck_phone_formatter_default' => array( ++- 'arguments' => array('element' => NULL), ++- ), ++- 'cck_phone_formatter_local' => array( ++- 'arguments' => array('element' => NULL), ++- ), ++- 'cck_phone_mobile_tel' => array( ++- 'arguments' => array('element' => NULL, 'phone' => ''), +++ 'label' => t('Phone number'), +++ 'description' => t('Defines a field type for phone numbers.'), +++ 'settings' => array( +++ 'textfield_size' => CCK_PHONE_TEXTFIELD_MAX_LENGTH, +++ ), +++ 'instance_settings' => array( +++ 'default_country' => NULL, +++ 'all_country_codes' => TRUE, +++ 'phone_as_link' => TRUE, +++ ), +++ 'default_widget' => 'phone_textfield', +++ 'default_formatter' => 'phone_formatter', ++ ), ++ ); ++ } ++ +++/** +++ * Implements hook_field_settings_form(). +++ */ +++function cck_phone_field_settings_form($field, $instance) { +++ $form = array(); +++ $defaults = field_info_field_settings($field['type']); +++ $settings = array_merge($defaults, $field['settings']); +++ $form['textfield_size'] = array( +++ '#type' => 'textfield', +++ '#title' => t('Size of textfield'), +++ '#default_value' => $settings['textfield_size'], +++ '#description' => t('Enter phone number textfield\'s width.'), +++ ); +++ return $form; +++} +++ +++/** +++ * Implements hook_field_instance_settings_form(). +++ */ +++function cck_phone_field_instance_settings_form($field, $instance) { +++ drupal_add_css(drupal_get_path('module', 'cck_phone') . '/css/cck_phone.css'); +++ drupal_add_js(drupal_get_path('module', 'cck_phone') . '/js/cck_phone.manage_field.js'); +++ $form = array(); +++ $defaults = field_info_instance_settings($field['type']); +++ $settings = array_merge($defaults, $instance['settings']); +++ $cc_options = _cck_phone_cc_options(TRUE); +++ $form['default_country'] = array( +++ '#type' => 'select', +++ '#title' => t('Default country code'), +++ '#default_value' => $settings['default_country'], +++ '#options' => $cc_options, +++ '#weight' => 1, +++ ); +++ $form['all_country_codes'] = array( +++ '#type' => 'checkbox', +++ '#title' => t('Show all country codes.'), +++ '#default_value' => $settings['all_country_codes'], +++ '#description' => t('Uncheck this to select the country to be displayed.'), +++ '#weight' => 1.1, +++ ); +++ // Country codes settings +++ $form['country_codes'] = array( +++ '#type' => 'fieldset', +++ '#title' => 'Country selection', +++ '#attributes' => array('class' => array('cck-phone-settings')), +++ '#collapsible' => TRUE, +++ '#collapsed' => TRUE, +++ '#weight' => 2, +++ '#description' => t('Country marks with * has custom country code settings and/or validation.'), +++ ); +++ $form['country_codes']['country_selection'] = array( +++ '#type' => 'checkboxes', +++ '#title' => t('Select country codes to be included'), +++ '#default_value' => isset($instance['settings']['country_codes']['country_selection']) && !empty($instance['settings']['country_codes']['country_selection']) ? $instance['settings']['country_codes']['country_selection'] : array($instance['settings']['default_country'] => $instance['settings']['default_country']), +++ '#options' => $cc_options, +++ ); +++ // We don't need to detect if the device is mobile. RDFA FOAF states: +++ // A phone, specified using fully qualified tel: URI scheme +++ // (http://xmlns.com/foaf/spec/#term_phone) +++ $form['phone_as_link'] = array( +++ '#type' => 'checkbox', +++ '#title' => t('Display phone number as link. !foaf: A phone, specified using fully qualified tel: URI scheme', array('!foaf' => l('RDFA FOAF', 'http://xmlns.com/foaf/spec/#term_phone'))), +++ '#default_value' => $settings['phone_as_link'], +++ '#weight' => 3, +++ ); +++ return $form; +++} ++ ++ /** ++- * Implementation of hook_field_info(). +++ * Implements hook_field_schema(). ++ */ ++-function cck_phone_field_info() { +++function cck_phone_field_schema($field) { ++ return array( ++- 'phone_number' => array( ++- 'label' => t('Phone number'), ++- 'description' => t('Store a number and country code in the database to assemble a phone number.'), +++ 'columns' => array( +++ 'country' => array( +++ 'type' => 'varchar', +++ 'length' => 2, +++ 'not null' => TRUE, +++ 'description' => t('ISO 3166 2-character country code.'), +++ ), +++ 'int_code' => array( +++ 'type' => 'int', +++ 'not null' => TRUE, +++ 'description' => t('International country calling code.'), +++ ), +++ 'value' => array( +++ 'type' => 'varchar', +++ 'length' => CCK_PHONE_PHONE_MAX_LENGTH, +++ 'not null' => TRUE, +++ 'description' => t('Sanitized phone number with area code.'), +++ ), +++ ), +++ 'indexes' => array( +++ 'value_index' => array('value'), ++ ), ++ ); ++ } ++ ++ /** ++- * Implementation of hook_field_settings(). +++ * Implements hook_field_validate(). ++ */ ++-function cck_phone_field_settings($op, $field) { ++- switch ($op) { ++- case 'form': ++- drupal_add_css(drupal_get_path('module', 'cck_phone') . '/cck_phone.css'); ++- drupal_add_js(drupal_get_path('module', 'cck_phone') . '/cck_phone.js'); ++- ++- $form = array(); ++- $form['default_country'] = array( ++- '#type' => 'select', ++- '#title' => t('Default country code'), ++- '#default_value' => isset($field['default_country']) && ($field['default_country'] !== '') ? $field['default_country'] : NULL, ++- '#options' => _cck_phone_cc_options(TRUE), ++- ); ++- ++- $form['all_country_codes'] = array( ++- '#type' => 'checkbox', ++- '#title' => t('Show all country codes.'), ++- '#default_value' => isset($field['all_country_codes']) && ($field['all_country_codes'] !== '') ? $field['all_country_codes'] : TRUE, ++- '#description' => t('Uncheck this to select the country to be displayed.'), ++- ); ++- ++- // Country codes settings ++- $form['country_codes'] = array( ++- '#title' => 'Country selection', ++- '#type' => 'fieldset', ++- '#collapsible' => TRUE, ++- '#collapsed' => TRUE, ++- '#attributes' => array('class' => 'cck-phone-settings'), ++- ); ++- ++- $form['country_codes']['country_selection'] = array( ++- '#type' => 'checkboxes', ++- '#title' => t('Select country codes to be included'), ++- '#default_value' => isset($field['country_selection']) && !empty($field['country_selection']) ? $field['country_selection'] : array($field['default_country'] => $field['default_country']), ++- '#options' => _cck_phone_cc_options(TRUE), ++- '#description' => t('Country marks with * has custom country code settings and/or validation.'), ++- ); ++- ++- $form['enable_custom_country'] = array( ++- '#type' => 'checkbox', ++- '#title' => t('Enable country level validation'), ++- '#default_value' => isset($field['enable_custom_country']) && ($field['enable_custom_country'] !== '') ? $field['enable_custom_country'] : TRUE, ++- '#description' => t('Uncheck this to disable stringent country phone number validation.'), ++- ); ++- ++- $form['enable_extension'] = array( ++- '#type' => 'checkbox', ++- '#title' => t('Enable phone extension support'), ++- '#default_value' => isset($field['enable_extension']) && ($field['enable_extension'] !== '') ? $field['enable_extension'] : FALSE, ++- '#description' => t('Check this to enable phone number extension field.'), ++- ); ++- ++- $form['enable_mobile'] = array( ++- '#type' => 'checkbox', ++- '#title' => t('Enable mobile device detection'), ++- '#default_value' => isset($field['enable_mobile']) && ($field['enable_mobile'] !== '') ? $field['enable_mobile'] : FALSE, ++- '#description' => t('Check this to enable phone number link on mobile browsers (RFC3966).'), ++- ); ++- ++- // Display country specific settings ++- foreach (_cck_phone_custom_cc() as $cc) { ++- $function = $cc . '_phone_field_settings'; ++- if (function_exists($function)) { ++- $country_settings = $function($op, $field); ++- if (isset($country_settings) && !empty($country_settings)) { ++- $country_codes = cck_phone_countrycodes($cc); ++- // Wrap with fieldset ++- $wrapper = array( ++- '#title' => $country_codes['country'] . ' specific settings', ++- '#type' => 'fieldset', ++- '#collapsible' => TRUE, ++- '#collapsed' => TRUE, ++- '#attributes' => array('class' => 'cck-phone-settings cck-phone-settings-' . $cc), +++function cck_phone_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { +++ $field_name = $field['field_name']; +++ foreach ($items as $delta => $item) { +++ $phone_value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); +++ if (!empty($phone_value)) { +++ $subaddress_value = check_plain($item['subaddress_value']); +++ // Lenient checking, as long as it doesn't have invalid phone number characters +++ $regex = '/^ +++ [+\s.()-]* # optional separator +++ (?: # } +++ \d # } 4-15 digits number +++ [\s.()-]* # } each followed by optional separator +++ ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } +++ $/x'; +++ // Generic number validation +++ if (!preg_match($regex, $phone_value)) { +++ $errors[$field_name][$langcode][$delta][] = array( +++ 'error' => 'value', +++ 'message' => t('Phone number must be numeric and %min_length to %max_length length.', array('%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH)), +++ ); +++ } +++ else { +++ $code = $item['country']; +++ // Custom country level validation +++ $validate_function = $code . '_validate_number'; +++ $has_cc = module_load_include('inc', 'cck_phone', 'includes/phone.' . $code) && function_exists($validate_function); +++ if ($has_cc) { +++ if (!$validate_function($phone_value, '', $error_message)) { +++ $errors[$field_name][$langcode][$delta][] = array( +++ 'error' => 'value', +++ 'message' => $error_message, ++ ); ++- $wrapper[] = $country_settings; ++- array_push($form, $wrapper); ++ } ++ } ++ } ++- ++- return $form; ++- ++- case 'validate': ++- // Validate country specific settings ++- foreach (_cck_phone_custom_cc() as $cc) { ++- $function = $cc . '_phone_field_settings'; ++- if (function_exists($function)) { ++- $function($op, $field); ++- } ++- } ++- break; ++- ++- case 'save': ++- $settings = array('default_country', 'all_country_codes', 'country_selection', 'enable_custom_country', 'enable_extension', 'enable_mobile'); ++- ++- // Save country specific settings ++- foreach (_cck_phone_custom_cc() as $cc) { ++- $function = $cc . '_phone_field_settings'; ++- if (function_exists($function)) { ++- array_push($settings, $function($op, $field)); ++- } ++- } ++- return $settings; ++- ++- // TODO: filters for phone number? ++-// case 'filters': ++-// break; ++- ++- case 'database columns': ++- return array( ++- 'number' => array( ++- 'type' => 'varchar', ++- 'length' => CCK_PHONE_PHONE_MAX_LENGTH, ++- 'not null' => FALSE, ++- ), ++- 'country_codes' => array( ++- 'type' => 'varchar', ++- 'length' => CCK_PHONE_CC_MAX_LENGTH, ++- 'not null' => FALSE, ++- ), ++- 'extension' => array( ++- 'type' => 'varchar', ++- 'length' => CCK_PHONE_EXTENSION_MAX_LENGTH, ++- 'not null' => FALSE, ++- ), ++- ); +++ } ++ } ++ } ++ ++ /** ++- * Implementation of hook_field(). +++ * Implements hook_field_widget_error(). ++ */ ++-function cck_phone_field($op, &$node, $field, &$items, $teaser, $page) { ++- switch ($op) { ++- case 'validate': ++- foreach ($items as $delta => $value) { ++- _cck_phone_validate($items[$delta], $delta, $field, $node); ++- } ++- ++- return $items; ++- break; ++- ++- case 'presave': ++- foreach ($items as $delta => $value) { ++- _cck_phone_process($items[$delta], $delta, $field, $node); ++- } ++- break; ++- ++- // Do country level code need to modify the output? ++- case 'sanitize': ++- foreach ($items as $delta => $value) { ++- _cck_phone_sanitize($items[$delta], $delta, $field, $node); ++- } ++- break; +++function cck_phone_field_widget_error($element, $error, $form, &$form_state) { +++ $element['#parents'][] = $error['error']; +++ form_error($element, $error['message'], $form, $form_state); +++} ++ +++/** +++ * Implements hook_field_presave(). +++ */ +++function cck_phone_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { +++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); +++ $list = cck_phone_countrycodes(); +++ foreach ($items as $delta => $item) { +++ $code = $item['country']; +++ $value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); +++ $sanitize_number_function = $code . '_sanitize_number'; +++ if (function_exists($sanitize_number_function)) { +++ $sanitize_number_function($value); +++ } +++ $items[$delta]['value'] = $value; +++ $items[$delta]['int_code'] = (int) preg_replace('/^\+/', '', $list[$code]['code']); ++ } +++} ++ +++/** +++ * Implements hook_field_is_empty(). +++ */ +++function cck_phone_field_is_empty($item, $field) { +++ return empty($item['value']); ++ } ++ +++/************************************************************************** +++ * Field Type API: Widget +++ * +++ * The widget is the form element used to receive input from the user +++ * when the field is being populated. +++ **************************************************************************/ ++ /** ++- * Implementation of hook_field_formatter_info(). +++ * Implement hook_field_widget_info(). ++ */ ++-function cck_phone_field_formatter_info() { +++function cck_phone_field_widget_info() { ++ return array( ++- 'default' => array( ++- 'label' => 'Global phone number (default)', ++- 'field types' => array('phone_number'), ++- 'multiple values' => CONTENT_HANDLE_CORE, ++- ), ++- 'local' => array( ++- 'label' => 'Local phone number', +++ 'phone_textfield' => array( +++ 'label' => t('Textfield'), ++ 'field types' => array('phone_number'), ++- 'multiple values' => CONTENT_HANDLE_CORE, ++ ), ++ ); ++ } ++ ++ /** ++- * Theme function for phone extension. +++ * Implements hook_field_widget_form(). ++ */ ++-function theme_phone_number_extension($extension = '') { ++- return t(' ext. @extension', array('@extension' => $extension)); +++function cck_phone_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { +++ $field_name = $field['field_name']; +++ $elements = array(); +++ $elements['phone_field'] = $element; +++ $elements['phone_field']['#type'] = 'item'; +++ $elements['phone_field']['value'] = array( +++ '#type' => 'textfield', +++ '#size' => $field['settings']['textfield_size'] ? $field['settings']['textfield_size'] : CCK_PHONE_TEXTFIELD_MAX_LENGTH, +++ '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, +++ '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '', +++ '#parents' => array($field_name, $langcode, $delta, 'value'), +++ ); +++ if ($instance['widget']['type'] == 'phone_autocomplete') { +++ $elements['phone_field']['value']['#autocomplete_path'] = 'cck-phone/autocomplete/' . $field_name; +++ } +++ $elements['phone_field']['phone_advance'] = array( +++ '#type' => 'fieldset', +++ '#title' => t('Phone number options'), +++ '#collapsible' => TRUE, +++ '#collapsed' => TRUE, +++ ); +++ $elements['phone_field']['phone_advance']['country'] = array( +++ '#type' => 'select', +++ '#title' => t('Country code'), +++ '#default_value' => isset($items[$delta]['country']) ? $items[$delta]['country'] : $instance['settings']['default_country'], +++ '#parents' => array($field_name, $langcode, $delta, 'country'), +++ ); +++ if ($instance['settings']['all_country_codes']) { +++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(); +++ } +++ else { +++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(FALSE, $instance['settings']['country_codes']['country_selection']); +++ } +++ return $elements; ++ } ++ +++/*********************************************************************** +++ * Field Type API: Formatter +++ * +++ * These are the api hooks that present formatted (themed) output to the +++ * user. +++ **********************************************************************/ ++ /** ++- * Theme function for mobile tel. +++ *Implementation of hook_field_formatter_info(). ++ */ ++-function theme_cck_phone_mobile_tel($element, $phone = '') { ++- $item = $element['#item']; ++- ++- // Mobile browsers support ++- if (isset($item['mobile_output']) && $item['mobile_output'] == TRUE) { ++- // Always output as global phone number without separator, leave the $phone display unchanged ++- $cc = cck_phone_countrycodes($item['country_codes']); ++- $tel = $cc['code'] . $item['number']; ++- ++- $phone = '' . $phone . ''; ++- } ++- ++- return $phone; +++function cck_phone_field_formatter_info() { +++ return array( +++ 'phone_formatter' => array( +++ 'label' => t('Phone number'), +++ 'field types' => array('phone_number'), +++ ), +++ ); ++ } ++ ++ /** ++- * Theme function for 'default' or global phone number field formatter. +++ * Implements hook_field_formatter_view(). ++ */ ++-function theme_cck_phone_formatter_default($element) { ++- $item = $element['#item']; ++- $phone = ''; ++- ++- // Display a global phone number with country code. ++- if (!empty($item['number']) && !empty($item['country_codes'])) { ++- // Call country default formatter if exist ++- $function = $item['country_codes'] . '_formatter_default'; ++- if (function_exists($function)) { ++- $phone = $function($element); +++function cck_phone_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) { +++ $element = array(); +++ $type_class = array('type'); +++ foreach ($items as $delta => $item) { +++ $code = $item['country']; +++ $int_code = $item['int_code']; +++ $tel_value = '+' . $item['int_code'] . $item['value']; +++ $formatter_default_function = $code . '_formatter_default'; +++ module_load_include('inc', 'cck_phone', 'includes/phone.' . $code); +++ if (function_exists($formatter_default_function)) { +++ $format = $formatter_default_function($item['value']); ++ } ++ else { ++- $cc = cck_phone_countrycodes($item['country_codes']); ++- $phone = $cc['code'] .'-'. $item['number']; ++- } ++- ++- // Extension ++- if (!empty($item['extension'])) { ++- $phone = $phone . theme('phone_number_extension', $item['extension']); +++ $format = $item['value']; ++ } ++- ++- // Mobile browsers support ++- $phone = theme('cck_phone_mobile_tel', $element, $phone); +++ $details = array( +++ 'value' => $format, +++ 'int_code' => $int_code, +++ 'tel_value' => $tel_value, +++ ); +++ $element[$delta]['#markup'] = theme('phone_field_view', array('phone' => $details)); ++ } ++- ++- return $phone; +++ return $element; ++ } ++ ++ /** ++- * Theme function for 'local' phone number field formatter. +++ * Implementation of hook_theme() ++ */ ++-function theme_cck_phone_formatter_local($element) { ++- $item = $element['#item']; ++- $phone = ''; ++- ++- // Display a local phone number without country code. ++- if (!empty($item['number'])) { ++- // Call country local formatter if exist ++- $function = $item['country_codes'] . '_formatter_local'; ++- if (function_exists($function)) { ++- $phone = $function($element); ++- } ++- else { ++- $phone = $item['number']; ++- } ++- ++- // Extension ++- if (!empty($item['extension'])) { ++- $phone = $phone . theme('phone_number_extension', $item['extension']); ++- } ++- ++- // Mobile browsers support ++- $phone = theme('cck_phone_mobile_tel', $element, $phone); ++- } ++- ++- return $phone; +++function cck_phone_theme($existing, $type, $theme, $path) { +++ return array( +++ 'phone_field_view' => array( +++ 'render element' => 'phone', +++ 'template' => 'phone-field-view', +++ 'path' => drupal_get_path('module', 'cck_phone') . '/theme', +++ ), +++ ); ++ } ++ ++ /** ++@@ -350,16 +365,19 @@ ++ * @return string ++ */ ++ function _cck_phone_cc_options($show_custom = FALSE, $country_selection = array()) { +++ // Load country codes +++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); +++ ++ $options = array(); ++- ++ if ($show_custom) { ++ $custom_cc = _cck_phone_custom_cc(); ++ } ++- ++- foreach (cck_phone_countrycodes() as $cc => $value) { +++ +++ $list = cck_phone_countrycodes(); +++ foreach ($list as $cc => $value) { ++ $cc_name = $value['country'] .' ('. $value['code'] .')'; ++ ++- // faster using array key instead of in_array +++ // Faster using array key instead of in_array ++ if ($show_custom && isset($custom_cc[$cc])) { ++ $cc_name .= ' *'; ++ } ++@@ -380,401 +398,9 @@ ++ * Array of country codes abbreviation or FALSE if none exist. ++ */ ++ function _cck_phone_custom_cc() { ++- static $cc; ++- +++ $cc = &drupal_static(__FUNCTION__); ++ if (!isset($cc)) { ++ $cc = variable_get('cck_phone_custom_cc', FALSE); ++ } ++- ++ return $cc; ++-} ++- ++-function _cck_phone_valid_input($input) { ++- // lenient checking, as long as don't have invalid phone number character ++- $regex = '/^ ++- [\s.()-]* # optional separator ++- (?: # } ++- \d # } 4-15 digits number ++- [\s.()-]* # } each followed by optional separator ++- ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } ++- $/x'; ++- ++- return preg_match($regex, $input); ++-} ++- ++-function _cck_phone_valid_cc_input($list, $cc) { ++- if (isset($list[$cc]) && $list[$cc] == $cc) { ++- return TRUE; ++- } ++- ++- return FALSE; ++-} ++- ++-function _cck_phone_validate(&$item, $delta, $field, $node) { ++- $phone_input = trim($item['number']); ++- $countrycode = trim($item['country_codes']); ++- $ext_input = ''; ++- if ($field['enable_extension']) { ++- $ext_input = trim($item['extension']); ++- } ++- ++- if ($phone_input && !(isset($field['widget']['default_value'][$delta]['number']) && $phone_input == $field['widget']['default_value'][$delta]['number'] && !$field['required'])) { ++- ++- $error_params = array( ++- '%phone_input' => check_plain($phone_input), // original phone input ++- '%countrycode' => check_plain($countrycode), ++- '%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, ++- '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH, ++- '%ext_input' => check_plain($ext_input), ++- '%ext_max_length' => CCK_PHONE_EXTENSION_MAX_LENGTH, ++- ); ++- ++- // Only allow digit, dash, space and bracket ++- if (!_cck_phone_valid_input($phone_input, $ext_input)) { ++- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); ++- if ($field['enable_extension'] && $ext_input != '') { ++- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); ++- } ++- ++- form_set_error($field['field_name'], $error); ++- } ++- else { ++- if (!$field['all_country_codes']) { ++- if (!_cck_phone_valid_cc_input($field['country_selection'], $countrycode)) { ++- $error = t('Invalid country code "%countrycode" submitted.', $error_params); ++- form_set_error($field['field_name'], $error); ++- } ++- } ++- // Generic number validation ++- if (!cck_phone_validate_number($countrycode, $phone_input, $ext_input)) { ++- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); ++- if ($field['enable_extension'] && $ext_input != '') { ++- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); ++- } ++- ++- form_set_error($field['field_name'], $error); ++- } ++- // Country level validation if enabled ++- elseif ($field['enable_custom_country'] != 0 || is_null($field['enable_custom_country']) || !isset($field['enable_custom_country'])) { ++- $custom_cc = _cck_phone_custom_cc(); ++- ++- if (isset($custom_cc[$countrycode])) { ++- $validate_function = $countrycode . '_validate_number'; ++- ++- if (function_exists($validate_function)) { ++- $error = ''; ++- if (!$validate_function($phone_input, $ext_input, $error)) { ++- form_set_error($field['field_name'], t($error, $error_params)); ++- } ++- } ++- } ++- } ++- } ++- } ++-} ++- ++-function _cck_phone_process(&$item, $delta = 0, $field, $node) { ++- $widget = $field['widget']['default_value'][$delta]; ++- // Clean up the phone number. ++- $item['number'] = cck_phone_clean_number($item['number']); ++- $item['extension'] = cck_phone_clean_number($item['extension']); ++- ++- // Don't save an invalid default value. ++- if ((isset($widget['number']) && $item['number'] == $widget['number']) && (isset($widget['country_codes']) && $item['country_codes'] == $widget['country_codes']) && is_object($node)) { ++- if (!cck_phone_validate_number($item['country_codes'], $item['number'], $item['extension'])) { ++- unset($item['number']); ++- unset($item['country_codes']); ++- unset($item['extension']); ++- } ++- } ++-} ++- ++-/** ++- * Cleanup user-entered values for a phone number field according to field settings. ++- * ++- * @param $item ++- * A single phone number item, usually containing number and country code. ++- * @param $delta ++- * The delta value if this field is one of multiple fields. ++- * @param $field ++- * The CCK field definition. ++- * @param $node ++- * The node containing this phone number. ++- */ ++-function _cck_phone_sanitize(&$item, $delta, &$field, &$node) { ++- if (!empty($item['number'])) { ++- $cc = $item['country_codes']; ++- $item['number'] = cck_phone_clean_number($item['number']); ++- ++- $custom_cc = _cck_phone_custom_cc(); ++- if (isset($custom_cc[$cc])) { ++- $function = $cc . '_sanitize_number'; ++- ++- if (function_exists($function)) { ++- $function($item['number']); ++- } ++- } ++- } ++- ++- if ($field['enable_extension']) { ++- $item['extension'] = cck_phone_clean_number($item['extension']); ++- } ++- else { ++- unset($item['extension']); ++- } ++- ++- if ($field['enable_mobile'] && preg_match(CCK_PHONE_MOBILE_AGENT, drupal_strtolower($_SERVER['HTTP_USER_AGENT']))) { ++- $item['mobile_output'] = TRUE; ++- } ++-} ++- ++- ++-/** ++- * Implementation of hook_widget_info(). ++- */ ++-function cck_phone_widget_info() { ++- return array( ++- 'phone_number' => array( ++- 'label' => t('Phone number'), ++- 'field types' => array('phone_number'), ++- 'multiple values' => CONTENT_HANDLE_CORE, ++- ), ++- ); ++-} ++- ++-/** ++- * Implementation of hook_widget_settings(). ++- */ ++-function cck_phone_widget_settings($op, $widget) { ++- switch ($op) { ++- case 'form': ++- $form = array(); ++- $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : CCK_PHONE_PHONE_MAX_LENGTH; ++- $form['input']['size'] = array( ++- '#type' => 'textfield', ++- '#title' => t('Size of phone number textfield'), ++- '#default_value' => $size, ++- '#element_validate' => array('_element_validate_integer_positive'), ++- '#required' => TRUE, ++- '#description' => t('International number is maximum 15 digits with additional country code, default is %length.', array('%length' => CCK_PHONE_PHONE_MAX_LENGTH)), ++- ); ++- return $form; ++- ++- case 'save': ++- return array('size'); ++- } ++-} ++- ++-/** ++- * Implementation of hook_widget(). ++- */ ++-function cck_phone_widget(&$form, &$form_state, $field, $items, $delta = 0) { ++- $element = array( ++- '#type' => $field['widget']['type'], ++- '#default_value' => isset($items[$delta]) ? $items[$delta] : '', ++- '#title' => $field['widget']['label'], ++- '#weight' => $field['widget']['weight'], ++- '#description' => $field['widget']['description'], ++- '#required' => $field['required'], ++- '#field' => $field, ++- ); ++- return $element; ++-} ++- ++-/** ++- * Implementation of hook_content_is_empty(). ++- */ ++-function cck_phone_content_is_empty($item, $field) { ++- if (empty($item['number'])) { ++- return TRUE; ++- } ++- return FALSE; ++-} ++- ++-/** ++- * Implementation of FAPI hook_elements(). ++- */ ++-function cck_phone_elements() { ++- return array( ++- 'phone_number' => array( ++- '#input' => TRUE, ++- '#process' => array('cck_phone_process'), ++- '#autocomplete_path' => FALSE, ++- ), ++- ); ++-} ++- ++-/** ++- * FAPI theme for an individual phone number elements. ++- * ++- * The phone number is already rendered by the themes and the html ++- * output lives in $element['#children']. Override this theme to ++- * make custom changes to the output. ++- * ++- * $element['#title'] is the field title ++- * $element['#field_name'] contains the field name ++- * $element['#delta''] is the position of this element in the group ++- * $element['number] is the phone number ++- * $element['country_codes'] is the country code ++- */ ++-function theme_phone_number($element) { ++- drupal_add_css(drupal_get_path('module', 'cck_phone') .'/cck_phone.css'); ++- ++- // Prefix single value phone number fields with the name of the field. ++-// if (empty($element['#field']['multiple'])) { ++-// if (isset($element['number']) && isset($element['country_codes'])) { ++-// $element['number']['#title'] = $element['#title'] .' '. $element['number']['#title']; ++-// $element['country_codes']['#title'] = $element['#title'] .' '. $element['country_codes']['#title']; ++-// } ++-// elseif ($element['number']) { ++-// $element['number']['#title'] = $element['#title']; ++-// } ++-// } ++- ++- $output = ''; ++- ++- $output = '
*' : ''; ++- ++- if (!empty($element['#title'])) { ++- $title = $element['#title']; ++- if (!empty($element['number']['#id'])) { ++- $output .= ' \n"; ++- } ++- else { ++- $output .= ' \n"; ++- } ++- } ++- ++- $output .= '
'; ++- if (isset($element['number'])) { ++- $output .= '
'. theme('textfield', $element['number']) .'
'; ++- } ++- if (isset($element['extension'])) { ++- $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : ''; ++- $output .= '
'. $prefix . theme('textfield', $element['extension']) .'
'; ++- } ++- $output .= '
'. theme('select', $element['country_codes']) .'
'; ++- $output .= '
'; ++- ++- return $output; ++-} ++- ++-/** ++- * Process an individual element. ++- */ ++-function cck_phone_process($element, $edit, $form_state, $form) { ++- $field_name = $element['#field_name']; ++- $field = $form['#field_info'][$field_name]; ++- $field_key = $element['#columns'][0]; ++- $delta = $element['#delta']; ++- ++- $element['number'] = array( ++- '#type' => 'textfield', ++- '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, ++- '#size' => CCK_PHONE_PHONE_MAX_LENGTH, ++-// '#title' => t('Number'), ++- '#description' => $element['#description'], ++- '#required' => ($delta == 0 && $field['number'] !== 'optional') ? $element['#required'] : FALSE, ++- '#default_value' => isset($element['#value']['number']) ? $element['#value']['number'] : NULL, ++- ); ++- ++- if ($field['enable_extension']) { ++- $element['extension'] = array( ++- '#type' => 'textfield', ++- '#maxlength' => CCK_PHONE_EXTENSION_MAX_LENGTH, ++- '#size' => CCK_PHONE_EXTENSION_MAX_LENGTH, ++-// '#title' => t('ext'), ++- '#required' => FALSE, ++- '#default_value' => isset($element['#value']['extension']) ? $element['#value']['extension'] : NULL, ++- '#prefix' => '
'. t('ext') .'
', ++- ); ++- } ++- ++- $element['country_codes'] = array( ++- '#type' => 'select', ++-// '#title' => 'Country code', ++- '#default_value' => ($element['#value']['number'] != '' && isset($element['#value']['country_codes'])) ? $element['#value']['country_codes'] : (isset($field['default_country']) ? $field['default_country'] : NULL), ++- ); ++- if ($field['all_country_codes']) { ++- $element['country_codes']['#options'] = _cck_phone_cc_options(); ++- } ++- else { ++- $element['country_codes']['#options'] = _cck_phone_cc_options(FALSE, $field['country_selection']); ++- } ++- ++- return $element; ++-} ++- ++-/** ++- * Strip number of space, hash, dash, bracket, etc leaving digit only. ++- * ++- * @param string $number ++- * @return string Returns digit only phone number. ++- */ ++-function cck_phone_clean_number($number) { ++- // Remove none numeric characters ++- $number = preg_replace('/[^0-9]/', '', $number); ++- ++- return $number; ++-} ++- ++-/** ++- * Generic validation for Phone Number. ++- * ++- * @param string $countrycode ++- * @param string $number ++- * @return boolean Returns boolean FALSE if the phone number is not valid. ++- */ ++-function cck_phone_validate_number($countrycode, $number, $ext = '') { ++- // We don't want to worry about separators ++- $number = cck_phone_clean_number($number); ++- if ($number !== '' && drupal_strlen($number) > CCK_PHONE_PHONE_MAX_LENGTH) { ++- return FALSE; ++- } ++- ++- $ext = cck_phone_clean_number($ext); ++- if ($ext !== '' && drupal_strlen($ext) > CCK_PHONE_EXTENSION_MAX_LENGTH) { ++- return FALSE; ++- } ++- ++- return TRUE; ++-} ++- ++- ++-/* ------ Token ------ */ ++- ++-/** ++- * Implementation of hook_token_list(). ++- */ ++-function cck_phone_token_list($type = 'all') { ++- if ($type == 'field' || $type == 'all') { ++- $tokens = array(); ++- ++- $tokens['cck_phone']['number'] = t('Phone number'); ++- $tokens['cck_phone']['country_codes'] = t('Country code'); ++- $tokens['cck_phone']['extension'] = t('Extension'); ++- ++- return $tokens; ++- } ++-} ++- ++-/** ++- * Implementation of hook_token_values(). ++- */ ++-function cck_phone_token_values($type, $object = NULL, $options = array()) { ++- if ($type == 'field') { ++- $item = $object[0]; ++- ++- $tokens['number'] = $item['number']; ++- $tokens['country_codes'] = $item['country_codes']; ++- $tokens['cck_phone']['extension'] = $item['extension']; ++- ++- return $tokens; ++- } ++-} +++} ++\ No newline at end of file ++Index: includes/phone.ca.inc ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.ca.inc,v ++retrieving revision 1.1 ++diff -u -r1.1 phone.ca.inc ++--- includes/phone.ca.inc 8 Jul 2010 11:22:37 -0000 1.1 +++++ includes/phone.ca.inc 24 Jul 2010 06:02:20 -0000 ++@@ -7,23 +7,25 @@ ++ */ ++ ++ /** ++- * Verifies that $number is a valid ten-digit North American phone number. +++ * Validate country level phone number. ++ * ++ * @param $number ++- * Digits only value. ++- * @param $ext ++- * Digits only value. +++ * Digits only phone number value. +++ * @param $subaddress +++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, +++ * fax's T33 subaddress, modem's parameters/recommended parameters. +++ * Reference: http://tools.ietf.org/html/rfc2806. ++ * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number +++ * Error message that will be displayed to user. +++ * @param $phone_type +++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, +++ * Pager, BBS, Modem, Car, ISDN, PCS) ++ * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * TRUE if it is a valid phone number for this country, FALSE otherwise. ++ */ ++-function ca_validate_number($number, $ext = '', &$error) { ++- return us_validate_number($number, $ext = '', &$error); +++function ca_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { +++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); +++ return us_validate_number($number, $subaddress, $error, $phone_type); ++ } ++ ++ /** ++@@ -33,43 +35,17 @@ ++ * A single phone number item. ++ */ ++ function ca_sanitize_number(&$number) { +++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); ++ us_sanitize_number($number); ++ } ++ ++ /** ++ * Default formatter for international phone number. ++ * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++- */ ++-function ca_formatter_default($element) { ++- return us_formatter_default($element); ++-} ++- ++-/** ++- * Local formatter for local phone number. ++- * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * @param $number +++ * Phone number. ++ */ ++-function ca_formatter_local($element) { ++- return us_formatter_local($element); +++function ca_formatter_default($number) { +++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); +++ return us_formatter_default($number); ++ } ++\ No newline at end of file ++Index: includes/phone.gb.inc ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.gb.inc,v ++retrieving revision 1.1 ++diff -u -r1.1 phone.gb.inc ++--- includes/phone.gb.inc 8 Jul 2010 11:22:37 -0000 1.1 +++++ includes/phone.gb.inc 24 Jul 2010 07:12:33 -0000 ++@@ -25,29 +25,27 @@ ++ * Validate country level phone number. ++ * ++ * @param $number ++- * Digits only value. ++- * @param $ext ++- * Digits only value. +++ * Digits only phone number value. +++ * @param $subaddress +++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, +++ * fax's T33 subaddress, modem's parameters/recommended parameters. +++ * Reference: http://tools.ietf.org/html/rfc2806. ++ * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number +++ * Error message that will be displayed to user. +++ * @param $phone_type +++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, +++ * Pager, BBS, Modem, Car, ISDN, PCS) ++ * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * TRUE if it is a valid phone number for this country, FALSE otherwise. ++ */ ++-function gb_validate_number($number, $ext = '', &$error) { ++- // We don't want to worry about separators ++- $number = cck_phone_clean_number($number); ++- ++- if (preg_match(_uk_phone_rules(), $number)) { ++- return TRUE; +++function gb_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { +++ if (!empty($number)) { +++ if (preg_match(_uk_phone_rules(), $number)) { +++ return TRUE; +++ } +++ $error = t('"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "29 9999 9999", with optional leading "0"', array('%phone_input' => $number)); +++ return FALSE; ++ } ++- ++- // t() is no needed ++- $error = '"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "99 9999 9999", with optional leading "0"'; ++- return FALSE; ++ } ++ ++ /** ++@@ -64,58 +62,16 @@ ++ /** ++ * Default formatter for international phone number. ++ * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++- */ ++-function gb_formatter_default($element) { ++- $item = $element['#item']; ++- ++- // Display a global phone number with country code. ++- $cc = cck_phone_countrycodes($item['country_codes']); ++- ++- $result = preg_match(_uk_phone_rules, $item['number'], $matches); ++- ++- if ($result) { ++- // output as +44 AA BBBB CCCC, +44 AAA BBB CCCC or +44 AAAA BBB CCC ++- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++- } ++- ++- return $phone; ++-} ++- ++- ++-/** ++- * Local formatter for local phone number. ++- * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * @param $number +++ * Phone number. ++ */ ++-function gb_formatter_local($element) { ++- // Display a local phone number without country code. ++- $result = preg_match(_uk_phone_rules, $item['number'], $matches); +++function gb_formatter_default($number) { +++ $result = preg_match(_uk_phone_rules(), $number, $matches); ++ ++ if ($result) { ++- // output as 0AA BBBB CCCC, 0AAA BBB CCCC or 0AAAA BBB CCC ++- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++ // output as AA BBBB CCCC, AAA BBB CCCC or AAAA BBB CCC +++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++ } ++ ++ return $phone; ++-} +++} ++\ No newline at end of file ++Index: includes/phone.my.inc ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.my.inc,v ++retrieving revision 1.1 ++diff -u -r1.1 phone.my.inc ++--- includes/phone.my.inc 8 Jul 2010 11:22:37 -0000 1.1 +++++ includes/phone.my.inc 24 Jul 2010 07:08:18 -0000 ++@@ -45,78 +45,64 @@ ++ } ++ ++ /** ++- * Verifies that $number is a valid Malaysia phone number. +++ * Validate country level phone number. ++ * ++ * @param $number ++- * Digits only value. ++- * @param $ext ++- * Digits only value. +++ * Digits only phone number value. +++ * @param $subaddress +++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, +++ * fax's T33 subaddress, modem's parameters/recommended parameters. +++ * Reference: http://tools.ietf.org/html/rfc2806. ++ * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number +++ * Error message that will be displayed to user. +++ * @param $phone_type +++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, +++ * Pager, BBS, Modem, Car, ISDN, PCS) ++ * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * TRUE if it is a valid phone number for this country, FALSE otherwise. ++ */ ++-function my_validate_number($number, $ext = '', &$error) { ++- // We don't want to worry about separators ++- $number = cck_phone_clean_number($number); ++- ++- foreach (_my_phone_rules() as $rule) { ++- // define regular expression ++- $regex = '/^ ++- ([0]*) # an optional 0 ++- ('. $rule[0] .') # area code ++- \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] ++- $/x'; ++- ++- $result = preg_match($regex, $number, $matches); ++- ++- if ($result) { ++- return TRUE; +++function my_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { +++ if (!empty($number)) { +++ foreach (_my_phone_rules() as $rule) { +++ // define regular expression +++ $regex = '/^ +++ ([0]*) # an optional 0 +++ ('. $rule[0] .') # area code +++ \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] +++ $/x'; +++ +++ $result = preg_match($regex, $number, $matches); +++ +++ if ($result) { +++ return TRUE; +++ } ++ } +++ $error = t('"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.', array('%phone_input' => $number)); +++ return FALSE; ++ } ++- ++- // t() is no needed ++- $error = '"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.'; ++- return FALSE; ++ } ++ ++ /** ++- * Cleanup user-entered values for a phone number field for saving to DB. +++ * Cleanup user-entered values for a phone number field for storing to DB. ++ * ++ * @param $number ++ * A single phone number item. +++ * @param $href +++ * Valid number (numeric and + charaters only) placed at +++ * href="tel:;ext=123" of anchor tag. ++ */ ++ function my_sanitize_number(&$number) { ++ // Remove trunk prefix '0' ++- ++ $number = preg_replace('/^([0]*)/', '', $number); ++ } ++ ++ /** ++ * Default formatter for international phone number. ++ * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * @param $number +++ * Phone number. ++ */ ++-function my_formatter_default($element) { ++- $item = $element['#item']; ++- ++- // Display a global phone number with country code. ++- $cc = cck_phone_countrycodes($item['country_codes']); ++- +++function my_formatter_default($number) { ++ // Format the phone number however you like, this is the default ++ foreach (_my_phone_rules() as $rule) { ++ // define regular expression ++@@ -125,55 +111,14 @@ ++ (\d{3,4}) ++ (\d{4}) ++ $/x'; ++- ++- $result = preg_match($regex, $item['number'], $matches); +++ $result = preg_match($regex, $number, $matches); ++ ++ if ($result) { ++- // output as +60A-BBB CCCC or +60A-BBBB CCCC ++- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++ // output as A-BBB CCCC +++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++ ++ continue; ++ } ++ } ++- ++- return $phone . $ext; ++-} ++- ++-/** ++- * Local formatter for local phone number. ++- * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++- */ ++-function my_formatter_local($element) { ++- // Display a local phone number without country code. ++- $phone = $element['#item']['number']; ++- ++- foreach (_my_phone_rules() as $rule) { ++- // define regular expression ++- $regex = '/^ ++- ('. $rule[0] .') # area code ++- (\d{3,4}) ++- (\d{4}) ++- $/x'; ++- ++- $result = preg_match($regex, $phone, $matches); ++- ++- if ($result) { ++- // output as 0A-BBB CCCC or 0A-BBBB CCCC ++- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++- continue; ++- } ++- } ++- ++ return $phone; ++-} +++} ++\ No newline at end of file ++Index: includes/phone.us.inc ++=================================================================== ++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.us.inc,v ++retrieving revision 1.1 ++diff -u -r1.1 phone.us.inc ++--- includes/phone.us.inc 8 Jul 2010 11:22:37 -0000 1.1 +++++ includes/phone.us.inc 24 Jul 2010 06:51:51 -0000 ++@@ -7,48 +7,45 @@ ++ */ ++ ++ /** ++- * Verifies that $number is a valid ten-digit North American phone number. +++ * Validate country level phone number. ++ * ++ * @param $number ++- * Digits only value. ++- * @param $ext ++- * Digits only value. +++ * Digits only phone number value. +++ * @param $subaddress +++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, +++ * fax's T33 subaddress, modem's parameters/recommended parameters. +++ * Reference: http://tools.ietf.org/html/rfc2806. ++ * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number +++ * Error message that will be displayed to user. +++ * @param $phone_type +++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, +++ * Pager, BBS, Modem, Car, ISDN, PCS) ++ * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * TRUE if it is a valid phone number for this country, FALSE otherwise. ++ */ ++-function us_validate_number($number, $ext = '', &$error) { ++- // Don't need to check for extension because it has been checked by generic validation as all digits, unless has special format/requirements ++- // We don't want to worry about separators ++- $number = cck_phone_clean_number($number); ++- ++- // define regular expression ++- $regex = '/^ ++- ([1]*) # an optional 1 ++- [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) ++- [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) ++- \d{4} # 4-digit line number ++- $/x'; ++- ++- $result = preg_match($regex, $number, $matches); ++- ++- if ($result && $matches[1] == '') { ++- return TRUE; ++- } ++- elseif ($result && $matches[1] == '1') { ++- // t() is no needed ++- $error = 'Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'; ++- return FALSE; ++- } ++- else { ++- // t() is no needed ++- $error = '"%phone_input" is not a valid North American phone number, it should be 10 digits number like "999 999 9999"'; ++- return FALSE; +++function us_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { +++ if (!empty($number)) { +++ // Define regular expression +++ $regex = '/^ +++ ([1]*) # an optional 1 +++ [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) +++ [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) +++ \d{4} # 4-digit line number +++ $/x'; +++ +++ $result = preg_match($regex, $number, $matches); +++ +++ if ($result && $matches[1] == '') { +++ return TRUE; +++ } +++ elseif ($result && $matches[1] == '1') { +++ $error = t('Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'); +++ return FALSE; +++ } +++ else { +++ $error = t('%phone_input is not a valid North American phone number, it should be 10 digits number like "989 999 9999"', array('%phone_input' => $number)); +++ return FALSE; +++ } ++ } ++ } ++ ++@@ -68,25 +65,10 @@ ++ /** ++ * Default formatter for international phone number. ++ * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++ * @param $number +++ * Phone number. ++ */ ++-function us_formatter_default($element) { ++- $item = $element['#item']; ++- $phone = ''; ++- ++- // Display a global phone number with country code. ++- $cc = cck_phone_countrycodes($item['country_codes']); ++- +++function us_formatter_default($number) { ++ // Format the phone number however you like, this is the default ++ // define regular expression ++ $regex = '/^ ++@@ -95,43 +77,7 @@ ++ (\d{4}) # 4-digit line number ++ /x'; ++ ++- $result = preg_match($regex, $item['number'], $matches); ++- ++- if ($result) { ++- // output as +1 (AAA) BBB CCCC ++- $phone = $cc['code'] .' ('. $matches[1] .') '. $matches[2] .' '. $matches[3]; ++- } ++- ++- return $phone . $ext; ++-} ++- ++-/** ++- * Local formatter for local phone number. ++- * ++- * @param $element ++- * $element['#item']['country_codes']: alpha-2 country code ++- * $element['#item']['number']: phone number ++- * @param $error ++- * The error message to shown to user. ++- * Available parameters to use in the error message are ++- * - "%countrycode": the alpha-2 CC ++- * - "%phone_input": the original number input by user (could be invalid) ++- * - "%max_length": allowed maximum length of the phone number ++- * @return boolean ++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++- */ ++-function us_formatter_local($element) { ++- $item = $element['#item']; ++- $phone = ''; ++- ++- // Display a local phone number without country code. ++- $regex = '/^ ++- ([2-9][0-8]\d) # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) ++- ([2-9]\d{2}) # 3-digit prefix (cannot start with 0 or 1) ++- (\d{4}) # 4-digit line number ++- /x'; ++- ++- $result = preg_match($regex, $item['number'], $matches); +++ $result = preg_match($regex, $number, $matches); ++ ++ if ($result) { ++ // output as (AAA) BBB CCCC ++@@ -139,4 +85,4 @@ ++ } ++ ++ return $phone; ++-} +++} ++\ No newline at end of file ++--- cck_phone.patch +++++ cck_phone.patch ++@@ -0,0 +1,2625 @@ +++Index: cck_phone.info +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.info,v +++retrieving revision 1.1 +++diff -u -r1.1 cck_phone.info +++--- cck_phone.info 8 Jul 2010 11:20:27 -0000 1.1 ++++++ cck_phone.info 22 Jul 2010 13:11:15 -0000 +++@@ -1,7 +1,18 @@ +++ ; $Id: cck_phone.info,v 1.1 2010/07/08 11:20:27 ckng Exp $ +++-name = Phone Number +++-description = "The phone module allows administrators to define a CCK field type for phone numbers." ++++name = Phone number ++++description = Defines a field type for phone number. +++ package = CCK +++-dependencies[] = content +++-core = 6.x +++- ++++core = 7.x ++++files[] = cck_phone.module ++++files[] = theme/phone-field-view.tpl.php ++++files[] = includes/cck_phone_countrycodes.inc ++++files[] = includes/phone.ca.inc ++++files[] = includes/phone.gb.inc ++++files[] = includes/phone.my.inc ++++files[] = includes/phone.ph.inc ++++files[] = includes/phone.us.inc ++++files[] = tests/cck_phone.crud.test ++++files[] = tests/cck_phone.crud_input.test ++++files[] = tests/phone.gb.test ++++files[] = tests/phone.my.test ++++files[] = tests/phone.us.test +++\ No newline at end of file +++Index: cck_phone.install +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.install,v +++retrieving revision 1.1 +++diff -u -r1.1 cck_phone.install +++--- cck_phone.install 8 Jul 2010 11:20:27 -0000 1.1 ++++++ cck_phone.install 23 Jul 2010 11:58:48 -0000 +++@@ -7,13 +7,12 @@ +++ * Installation file +++ */ +++ +++- ++++ +++ /** +++- * Implementation of hook_install(). +++- */ ++++* Implementation of hook_install(). ++++*/ +++ function cck_phone_install() { +++- drupal_load('module', 'content'); +++- content_notify('install', 'cck_phone'); ++++ _cck_phone_update_country_code_list(); +++ drupal_set_message(st('Phone number module installed successfully.')); +++ } +++ +++@@ -21,27 +20,51 @@ +++ * Implementation of hook_uninstall(). +++ */ +++ function cck_phone_uninstall() { +++- drupal_load('module', 'content'); +++- content_notify('uninstall', 'cck_phone'); ++++ variable_del('cck_phone_custom_cc'); +++ } +++ +++ /** +++ * Implementation of hook_enable(). +++- * +++- * Notify content module when this module is enabled. +++ */ +++ function cck_phone_enable() { +++ // TODO: Migration path for phone.module to cck_phone +++- drupal_load('module', 'content'); +++- content_notify('enable', 'cck_phone'); +++ } +++ +++ /** +++ * Implementation of hook_disable(). +++- * +++- * Notify content module when this module is disabled. +++ */ +++ function cck_phone_disable() { +++- drupal_load('module', 'content'); +++- content_notify('disable', 'cck_phone'); ++++ ++++} ++++ ++++/** ++++ * Update list of country codes phone validation. ++++ */ ++++function cck_phone_update_7000() { ++++ _cck_phone_update_country_code_list(); +++ } ++++ ++++/** ++++ * Store country code phone validation. ++++ * ++++ * This function should be called only at hook_update_N() ++++ * when new country phone library is added. ++++ */ ++++function _cck_phone_update_country_code_list() { ++++ // This function is too expensive to call at hook_init() and ++++ // should be called only if there's a new country code added. ++++ ++++ // Load custom country codes phone number includes ++++ $path = drupal_get_path('module', 'cck_phone') .'/includes'; ++++ // Scan include phone numbers directory ++++ $files = file_scan_directory($path, '/^phone\..*\.inc$/'); ++++ ++++ $countrycodes = array(); ++++ foreach ($files as $file) { ++++ list ($dummy, $countrycode) = explode('.', $file->name); ++++ // Faster using array key ++++ $countrycodes[$countrycode] = $countrycode; ++++ } ++++ // Save the list of country codes phone validation ++++ variable_set('cck_phone_custom_cc', $countrycodes); ++++} +++\ No newline at end of file +++Index: cck_phone.module +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/cck_phone.module,v +++retrieving revision 1.3 +++diff -u -r1.3 cck_phone.module +++--- cck_phone.module 12 Jul 2010 09:54:52 -0000 1.3 ++++++ cck_phone.module 26 Jul 2010 13:54:58 -0000 +++@@ -3,341 +3,321 @@ +++ +++ /** +++ * @file +++- * Defines phone number fields for CCK. ++++ * Defines a field type for phone numbers. +++ * Provide some verifications on the phone numbers +++ */ +++ +++ define('CCK_PHONE_PHONE_MIN_LENGTH', 4); // Is there a phone number less than 4 digits? +++ define('CCK_PHONE_PHONE_MAX_LENGTH', 15); // International standard 15 digits +++ define('CCK_PHONE_EXTENSION_MAX_LENGTH', 6); +++-define('CCK_PHONE_CC_MAX_LENGTH', 2); +++-define('CCK_PHONE_MOBILE_AGENT', '/(ipod|iphone|android|blackberry|palm|nokia|opera\s+mobi|opera\s+mini|windows\s+ce|iemobile)/i'); ++++define('CCK_PHONE_TEXTFIELD_MAX_LENGTH', 60); +++ +++ /** +++- * Implementation of hook_init(). +++- * This hook is called on module initialization. +++- */ +++-function cck_phone_init() { +++- // load country codes +++- module_load_include('inc', 'cck_phone', 'cck_phone_countrycodes'); +++- +++- // load custom country codes phone number includes +++- $path = drupal_get_path('module', 'cck_phone') .'/includes'; +++- // scan include phone numbers directory +++- $files = file_scan_directory($path, '^phone\..*\.inc$'); +++- +++- $countrycodes = array(); +++- foreach ($files as $file) { +++- module_load_include('inc', 'cck_phone', '/includes/'. $file->name); +++- list ($dummy, $countrycode) = explode('.', $file->name); +++- // faster using array key +++- $countrycodes[$countrycode] = $countrycode; +++- } +++- +++- // save the list of country codes phone validation +++- variable_set('cck_phone_custom_cc', $countrycodes); +++-} +++- +++-/** +++- * Implementation of hook_theme(). ++++ * Implementation of hook_field_info(). +++ */ +++-function cck_phone_theme() { ++++function cck_phone_field_info() { +++ return array( +++ 'phone_number' => array( +++- 'arguments' => array('element' => NULL), +++- ), +++- 'phone_number_extension' => array( +++- 'arguments' => array('extension' => ''), +++- ), +++- 'cck_phone_formatter_default' => array( +++- 'arguments' => array('element' => NULL), +++- ), +++- 'cck_phone_formatter_local' => array( +++- 'arguments' => array('element' => NULL), +++- ), +++- 'cck_phone_mobile_tel' => array( +++- 'arguments' => array('element' => NULL, 'phone' => ''), ++++ 'label' => t('Phone number'), ++++ 'description' => t('Defines a field type for phone numbers.'), ++++ 'settings' => array( ++++ 'textfield_size' => CCK_PHONE_TEXTFIELD_MAX_LENGTH, ++++ ), ++++ 'instance_settings' => array( ++++ 'default_country' => NULL, ++++ 'all_country_codes' => TRUE, ++++ 'phone_as_link' => TRUE, ++++ ), ++++ 'default_widget' => 'phone_textfield', ++++ 'default_formatter' => 'phone_formatter', +++ ), +++ ); +++ } +++ ++++/** ++++ * Implements hook_field_settings_form(). ++++ */ ++++function cck_phone_field_settings_form($field, $instance) { ++++ $form = array(); ++++ $defaults = field_info_field_settings($field['type']); ++++ $settings = array_merge($defaults, $field['settings']); ++++ $form['textfield_size'] = array( ++++ '#type' => 'textfield', ++++ '#title' => t('Size of textfield'), ++++ '#default_value' => $settings['textfield_size'], ++++ '#description' => t('Enter phone number textfield\'s width.'), ++++ ); ++++ return $form; ++++} ++++ ++++/** ++++ * Implements hook_field_instance_settings_form(). ++++ */ ++++function cck_phone_field_instance_settings_form($field, $instance) { ++++ drupal_add_css(drupal_get_path('module', 'cck_phone') . '/css/cck_phone.css'); ++++ drupal_add_js(drupal_get_path('module', 'cck_phone') . '/js/cck_phone.manage_field.js'); ++++ $form = array(); ++++ $defaults = field_info_instance_settings($field['type']); ++++ $settings = array_merge($defaults, $instance['settings']); ++++ $cc_options = _cck_phone_cc_options(TRUE); ++++ $form['default_country'] = array( ++++ '#type' => 'select', ++++ '#title' => t('Default country code'), ++++ '#default_value' => $settings['default_country'], ++++ '#options' => $cc_options, ++++ '#weight' => 1, ++++ ); ++++ $form['all_country_codes'] = array( ++++ '#type' => 'checkbox', ++++ '#title' => t('Show all country codes.'), ++++ '#default_value' => $settings['all_country_codes'], ++++ '#description' => t('Uncheck this to select the country to be displayed.'), ++++ '#weight' => 1.1, ++++ ); ++++ // Country codes settings ++++ $form['country_codes'] = array( ++++ '#type' => 'fieldset', ++++ '#title' => 'Country selection', ++++ '#attributes' => array('class' => array('cck-phone-settings')), ++++ '#collapsible' => TRUE, ++++ '#collapsed' => TRUE, ++++ '#weight' => 2, ++++ '#description' => t('Country marks with * has custom country code settings and/or validation.'), ++++ ); ++++ $form['country_codes']['country_selection'] = array( ++++ '#type' => 'checkboxes', ++++ '#title' => t('Select country codes to be included'), ++++ '#default_value' => isset($instance['settings']['country_codes']['country_selection']) && !empty($instance['settings']['country_codes']['country_selection']) ? $instance['settings']['country_codes']['country_selection'] : array($instance['settings']['default_country'] => $instance['settings']['default_country']), ++++ '#options' => $cc_options, ++++ ); ++++ // We don't need to detect if the device is mobile. RDFA FOAF states: ++++ // A phone, specified using fully qualified tel: URI scheme ++++ // (http://xmlns.com/foaf/spec/#term_phone) ++++ $form['phone_as_link'] = array( ++++ '#type' => 'checkbox', ++++ '#title' => t('Display phone number as link. !foaf: A phone, specified using fully qualified tel: URI scheme', array('!foaf' => l('RDFA FOAF', 'http://xmlns.com/foaf/spec/#term_phone'))), ++++ '#default_value' => $settings['phone_as_link'], ++++ '#weight' => 3, ++++ ); ++++ return $form; ++++} +++ +++ /** +++- * Implementation of hook_field_info(). ++++ * Implements hook_field_schema(). +++ */ +++-function cck_phone_field_info() { ++++function cck_phone_field_schema($field) { +++ return array( +++- 'phone_number' => array( +++- 'label' => t('Phone number'), +++- 'description' => t('Store a number and country code in the database to assemble a phone number.'), ++++ 'columns' => array( ++++ 'country' => array( ++++ 'type' => 'varchar', ++++ 'length' => 2, ++++ 'not null' => TRUE, ++++ 'description' => t('ISO 3166 2-character country code.'), ++++ ), ++++ 'int_code' => array( ++++ 'type' => 'int', ++++ 'not null' => TRUE, ++++ 'description' => t('International country calling code.'), ++++ ), ++++ 'value' => array( ++++ 'type' => 'varchar', ++++ 'length' => CCK_PHONE_PHONE_MAX_LENGTH, ++++ 'not null' => TRUE, ++++ 'description' => t('Sanitized phone number with area code.'), ++++ ), ++++ ), ++++ 'indexes' => array( ++++ 'value_index' => array('value'), +++ ), +++ ); +++ } +++ +++ /** +++- * Implementation of hook_field_settings(). ++++ * Implements hook_field_validate(). +++ */ +++-function cck_phone_field_settings($op, $field) { +++- switch ($op) { +++- case 'form': +++- drupal_add_css(drupal_get_path('module', 'cck_phone') . '/cck_phone.css'); +++- drupal_add_js(drupal_get_path('module', 'cck_phone') . '/cck_phone.js'); +++- +++- $form = array(); +++- $form['default_country'] = array( +++- '#type' => 'select', +++- '#title' => t('Default country code'), +++- '#default_value' => isset($field['default_country']) && ($field['default_country'] !== '') ? $field['default_country'] : NULL, +++- '#options' => _cck_phone_cc_options(TRUE), +++- ); +++- +++- $form['all_country_codes'] = array( +++- '#type' => 'checkbox', +++- '#title' => t('Show all country codes.'), +++- '#default_value' => isset($field['all_country_codes']) && ($field['all_country_codes'] !== '') ? $field['all_country_codes'] : TRUE, +++- '#description' => t('Uncheck this to select the country to be displayed.'), +++- ); +++- +++- // Country codes settings +++- $form['country_codes'] = array( +++- '#title' => 'Country selection', +++- '#type' => 'fieldset', +++- '#collapsible' => TRUE, +++- '#collapsed' => TRUE, +++- '#attributes' => array('class' => 'cck-phone-settings'), +++- ); +++- +++- $form['country_codes']['country_selection'] = array( +++- '#type' => 'checkboxes', +++- '#title' => t('Select country codes to be included'), +++- '#default_value' => isset($field['country_selection']) && !empty($field['country_selection']) ? $field['country_selection'] : array($field['default_country'] => $field['default_country']), +++- '#options' => _cck_phone_cc_options(TRUE), +++- '#description' => t('Country marks with * has custom country code settings and/or validation.'), +++- ); +++- +++- $form['enable_custom_country'] = array( +++- '#type' => 'checkbox', +++- '#title' => t('Enable country level validation'), +++- '#default_value' => isset($field['enable_custom_country']) && ($field['enable_custom_country'] !== '') ? $field['enable_custom_country'] : TRUE, +++- '#description' => t('Uncheck this to disable stringent country phone number validation.'), +++- ); +++- +++- $form['enable_extension'] = array( +++- '#type' => 'checkbox', +++- '#title' => t('Enable phone extension support'), +++- '#default_value' => isset($field['enable_extension']) && ($field['enable_extension'] !== '') ? $field['enable_extension'] : FALSE, +++- '#description' => t('Check this to enable phone number extension field.'), +++- ); +++- +++- $form['enable_mobile'] = array( +++- '#type' => 'checkbox', +++- '#title' => t('Enable mobile device detection'), +++- '#default_value' => isset($field['enable_mobile']) && ($field['enable_mobile'] !== '') ? $field['enable_mobile'] : FALSE, +++- '#description' => t('Check this to enable phone number link on mobile browsers (RFC3966).'), +++- ); +++- +++- // Display country specific settings +++- foreach (_cck_phone_custom_cc() as $cc) { +++- $function = $cc . '_phone_field_settings'; +++- if (function_exists($function)) { +++- $country_settings = $function($op, $field); +++- if (isset($country_settings) && !empty($country_settings)) { +++- $country_codes = cck_phone_countrycodes($cc); +++- // Wrap with fieldset +++- $wrapper = array( +++- '#title' => $country_codes['country'] . ' specific settings', +++- '#type' => 'fieldset', +++- '#collapsible' => TRUE, +++- '#collapsed' => TRUE, +++- '#attributes' => array('class' => 'cck-phone-settings cck-phone-settings-' . $cc), ++++function cck_phone_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { ++++ $field_name = $field['field_name']; ++++ foreach ($items as $delta => $item) { ++++ $phone_value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); ++++ if (!empty($phone_value)) { ++++ $subaddress_value = check_plain($item['subaddress_value']); ++++ // Lenient checking, as long as it doesn't have invalid phone number characters ++++ $regex = '/^ ++++ [+\s.()-]* # optional separator ++++ (?: # } ++++ \d # } 4-15 digits number ++++ [\s.()-]* # } each followed by optional separator ++++ ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } ++++ $/x'; ++++ // Generic number validation ++++ if (!preg_match($regex, $phone_value)) { ++++ $errors[$field_name][$langcode][$delta][] = array( ++++ 'error' => 'value', ++++ 'message' => t('Phone number must be numeric and %min_length to %max_length length.', array('%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH)), ++++ ); ++++ } ++++ else { ++++ $code = $item['country']; ++++ // Custom country level validation ++++ $validate_function = $code . '_validate_number'; ++++ $has_cc = module_load_include('inc', 'cck_phone', 'includes/phone.' . $code) && function_exists($validate_function); ++++ if ($has_cc) { ++++ if (!$validate_function($phone_value, '', $error_message)) { ++++ $errors[$field_name][$langcode][$delta][] = array( ++++ 'error' => 'value', ++++ 'message' => $error_message, +++ ); +++- $wrapper[] = $country_settings; +++- array_push($form, $wrapper); +++ } +++ } +++ } +++- +++- return $form; +++- +++- case 'validate': +++- // Validate country specific settings +++- foreach (_cck_phone_custom_cc() as $cc) { +++- $function = $cc . '_phone_field_settings'; +++- if (function_exists($function)) { +++- $function($op, $field); +++- } +++- } +++- break; +++- +++- case 'save': +++- $settings = array('default_country', 'all_country_codes', 'country_selection', 'enable_custom_country', 'enable_extension', 'enable_mobile'); +++- +++- // Save country specific settings +++- foreach (_cck_phone_custom_cc() as $cc) { +++- $function = $cc . '_phone_field_settings'; +++- if (function_exists($function)) { +++- array_push($settings, $function($op, $field)); +++- } +++- } +++- return $settings; +++- +++- // TODO: filters for phone number? +++-// case 'filters': +++-// break; +++- +++- case 'database columns': +++- return array( +++- 'number' => array( +++- 'type' => 'varchar', +++- 'length' => CCK_PHONE_PHONE_MAX_LENGTH, +++- 'not null' => FALSE, +++- ), +++- 'country_codes' => array( +++- 'type' => 'varchar', +++- 'length' => CCK_PHONE_CC_MAX_LENGTH, +++- 'not null' => FALSE, +++- ), +++- 'extension' => array( +++- 'type' => 'varchar', +++- 'length' => CCK_PHONE_EXTENSION_MAX_LENGTH, +++- 'not null' => FALSE, +++- ), +++- ); ++++ } +++ } +++ } +++ +++ /** +++- * Implementation of hook_field(). ++++ * Implements hook_field_widget_error(). +++ */ +++-function cck_phone_field($op, &$node, $field, &$items, $teaser, $page) { +++- switch ($op) { +++- case 'validate': +++- foreach ($items as $delta => $value) { +++- _cck_phone_validate($items[$delta], $delta, $field, $node); +++- } +++- +++- return $items; +++- break; +++- +++- case 'presave': +++- foreach ($items as $delta => $value) { +++- _cck_phone_process($items[$delta], $delta, $field, $node); +++- } +++- break; +++- +++- // Do country level code need to modify the output? +++- case 'sanitize': +++- foreach ($items as $delta => $value) { +++- _cck_phone_sanitize($items[$delta], $delta, $field, $node); +++- } +++- break; ++++function cck_phone_field_widget_error($element, $error, $form, &$form_state) { ++++ $element['#parents'][] = $error['error']; ++++ form_error($element, $error['message'], $form, $form_state); ++++} +++ ++++/** ++++ * Implements hook_field_presave(). ++++ */ ++++function cck_phone_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) { ++++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); ++++ $list = cck_phone_countrycodes(); ++++ foreach ($items as $delta => $item) { ++++ $code = $item['country']; ++++ $value = check_plain(preg_replace('/[^0-9]/', '', $item['value'])); ++++ $sanitize_number_function = $code . '_sanitize_number'; ++++ if (function_exists($sanitize_number_function)) { ++++ $sanitize_number_function($value); ++++ } ++++ $items[$delta]['value'] = $value; ++++ $items[$delta]['int_code'] = (int) preg_replace('/^\+/', '', $list[$code]['code']); +++ } ++++} +++ ++++/** ++++ * Implements hook_field_is_empty(). ++++ */ ++++function cck_phone_field_is_empty($item, $field) { ++++ return empty($item['value']); +++ } +++ ++++/************************************************************************** ++++ * Field Type API: Widget ++++ * ++++ * The widget is the form element used to receive input from the user ++++ * when the field is being populated. ++++ **************************************************************************/ +++ /** +++- * Implementation of hook_field_formatter_info(). ++++ * Implement hook_field_widget_info(). +++ */ +++-function cck_phone_field_formatter_info() { ++++function cck_phone_field_widget_info() { +++ return array( +++- 'default' => array( +++- 'label' => 'Global phone number (default)', ++++ 'phone_textfield' => array( ++++ 'label' => t('Textfield'), +++ 'field types' => array('phone_number'), +++- 'multiple values' => CONTENT_HANDLE_CORE, +++- ), +++- 'local' => array( +++- 'label' => 'Local phone number', +++- 'field types' => array('phone_number'), +++- 'multiple values' => CONTENT_HANDLE_CORE, +++ ), +++ ); +++ } +++ +++ /** +++- * Theme function for phone extension. ++++ * Implements hook_field_widget_form(). +++ */ +++-function theme_phone_number_extension($extension = '') { +++- return t(' ext. @extension', array('@extension' => $extension)); ++++function cck_phone_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { ++++ $field_name = $field['field_name']; ++++ $elements = array(); ++++ $elements['phone_field'] = $element; ++++ $elements['phone_field']['#type'] = 'item'; ++++ $elements['phone_field']['value'] = array( ++++ '#type' => 'textfield', ++++ '#size' => $field['settings']['textfield_size'] ? $field['settings']['textfield_size'] : CCK_PHONE_TEXTFIELD_MAX_LENGTH, ++++ '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, ++++ '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '', ++++ '#parents' => array($field_name, $langcode, $delta, 'value'), ++++ ); ++++ $elements['phone_field']['phone_advance'] = array( ++++ '#type' => 'fieldset', ++++ '#title' => t('Phone number options'), ++++ '#collapsible' => TRUE, ++++ '#collapsed' => TRUE, ++++ ); ++++ $elements['phone_field']['phone_advance']['country'] = array( ++++ '#type' => 'select', ++++ '#title' => t('Country code'), ++++ '#default_value' => isset($items[$delta]['country']) ? $items[$delta]['country'] : $instance['settings']['default_country'], ++++ '#parents' => array($field_name, $langcode, $delta, 'country'), ++++ ); ++++ if ($instance['settings']['all_country_codes']) { ++++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(); ++++ } ++++ else { ++++ $elements['phone_field']['phone_advance']['country']['#options'] = _cck_phone_cc_options(FALSE, $instance['settings']['country_codes']['country_selection']); ++++ } ++++ return $elements; +++ } +++ ++++/*********************************************************************** ++++ * Field Type API: Formatter ++++ * ++++ * These are the api hooks that present formatted (themed) output to the ++++ * user. ++++ **********************************************************************/ +++ /** +++- * Theme function for mobile tel. ++++ *Implementation of hook_field_formatter_info(). +++ */ +++-function theme_cck_phone_mobile_tel($element, $phone = '') { +++- $item = $element['#item']; +++- +++- // Mobile browsers support +++- if (isset($item['mobile_output']) && $item['mobile_output'] == TRUE) { +++- // Always output as global phone number without separator, leave the $phone display unchanged +++- $cc = cck_phone_countrycodes($item['country_codes']); +++- $tel = $cc['code'] . $item['number']; +++- +++- $phone = '' . $phone . ''; +++- } +++- +++- return $phone; ++++function cck_phone_field_formatter_info() { ++++ return array( ++++ 'phone_formatter' => array( ++++ 'label' => t('Phone number'), ++++ 'field types' => array('phone_number'), ++++ ), ++++ ); +++ } +++ +++ /** +++- * Theme function for 'default' or global phone number field formatter. ++++ * Implements hook_field_formatter_view(). +++ */ +++-function theme_cck_phone_formatter_default($element) { +++- $item = $element['#item']; +++- $phone = ''; +++- +++- // Display a global phone number with country code. +++- if (!empty($item['number']) && !empty($item['country_codes'])) { +++- // Call country default formatter if exist +++- $function = $item['country_codes'] . '_formatter_default'; +++- if (function_exists($function)) { +++- $phone = $function($element); ++++function cck_phone_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) { ++++ $element = array(); ++++ $type_class = array('type'); ++++ foreach ($items as $delta => $item) { ++++ $code = $item['country']; ++++ $int_code = $item['int_code']; ++++ $tel_value = '+' . $item['int_code'] . $item['value']; ++++ $formatter_default_function = $code . '_formatter_default'; ++++ module_load_include('inc', 'cck_phone', 'includes/phone.' . $code); ++++ if (function_exists($formatter_default_function)) { ++++ $format = $formatter_default_function($item['value']); +++ } +++ else { +++- $cc = cck_phone_countrycodes($item['country_codes']); +++- $phone = $cc['code'] .'-'. $item['number']; ++++ $format = $item['value']; +++ } +++- +++- // Extension +++- if (!empty($item['extension'])) { +++- $phone = $phone . theme('phone_number_extension', $item['extension']); +++- } +++- +++- // Mobile browsers support +++- $phone = theme('cck_phone_mobile_tel', $element, $phone); ++++ $details = array( ++++ 'value' => $format, ++++ 'int_code' => $int_code, ++++ 'tel_value' => $tel_value, ++++ ); ++++ $element[$delta]['#markup'] = theme('phone_field_view', array('phone' => $details)); +++ } +++- +++- return $phone; ++++ return $element; +++ } +++ +++ /** +++- * Theme function for 'local' phone number field formatter. ++++ * Implementation of hook_theme() +++ */ +++-function theme_cck_phone_formatter_local($element) { +++- $item = $element['#item']; +++- $phone = ''; +++- +++- // Display a local phone number without country code. +++- if (!empty($item['number'])) { +++- // Call country local formatter if exist +++- $function = $item['country_codes'] . '_formatter_local'; +++- if (function_exists($function)) { +++- $phone = $function($element); +++- } +++- else { +++- $phone = $item['number']; +++- } +++- +++- // Extension +++- if (!empty($item['extension'])) { +++- $phone = $phone . theme('phone_number_extension', $item['extension']); +++- } +++- +++- // Mobile browsers support +++- $phone = theme('cck_phone_mobile_tel', $element, $phone); +++- } +++- +++- return $phone; ++++function cck_phone_theme($existing, $type, $theme, $path) { ++++ return array( ++++ 'phone_field_view' => array( ++++ 'render element' => 'phone', ++++ 'template' => 'phone-field-view', ++++ 'path' => drupal_get_path('module', 'cck_phone') . '/theme', ++++ ), ++++ ); +++ } +++ +++ /** +++@@ -350,16 +330,19 @@ +++ * @return string +++ */ +++ function _cck_phone_cc_options($show_custom = FALSE, $country_selection = array()) { ++++ // Load country codes ++++ module_load_include('inc', 'cck_phone', 'includes/cck_phone_countrycodes'); ++++ +++ $options = array(); +++- +++ if ($show_custom) { +++ $custom_cc = _cck_phone_custom_cc(); +++ } +++- +++- foreach (cck_phone_countrycodes() as $cc => $value) { ++++ ++++ $list = cck_phone_countrycodes(); ++++ foreach ($list as $cc => $value) { +++ $cc_name = $value['country'] .' ('. $value['code'] .')'; +++ +++- // faster using array key instead of in_array ++++ // Faster using array key instead of in_array +++ if ($show_custom && isset($custom_cc[$cc])) { +++ $cc_name .= ' *'; +++ } +++@@ -380,401 +363,9 @@ +++ * Array of country codes abbreviation or FALSE if none exist. +++ */ +++ function _cck_phone_custom_cc() { +++- static $cc; +++- ++++ $cc = &drupal_static(__FUNCTION__); +++ if (!isset($cc)) { +++ $cc = variable_get('cck_phone_custom_cc', FALSE); +++ } +++- +++ return $cc; +++-} +++- +++-function _cck_phone_valid_input($input) { +++- // lenient checking, as long as don't have invalid phone number character +++- $regex = '/^ +++- [\s.()-]* # optional separator +++- (?: # } +++- \d # } 4-15 digits number +++- [\s.()-]* # } each followed by optional separator +++- ){'. CCK_PHONE_PHONE_MIN_LENGTH .','. CCK_PHONE_PHONE_MAX_LENGTH .'} # } +++- $/x'; +++- +++- return preg_match($regex, $input); +++-} +++- +++-function _cck_phone_valid_cc_input($list, $cc) { +++- if (isset($list[$cc]) && $list[$cc] == $cc) { +++- return TRUE; +++- } +++- +++- return FALSE; +++-} +++- +++-function _cck_phone_validate(&$item, $delta, $field, $node) { +++- $phone_input = trim($item['number']); +++- $countrycode = trim($item['country_codes']); +++- $ext_input = ''; +++- if ($field['enable_extension']) { +++- $ext_input = trim($item['extension']); +++- } +++- +++- if ($phone_input && !(isset($field['widget']['default_value'][$delta]['number']) && $phone_input == $field['widget']['default_value'][$delta]['number'] && !$field['required'])) { +++- +++- $error_params = array( +++- '%phone_input' => check_plain($phone_input), // original phone input +++- '%countrycode' => check_plain($countrycode), +++- '%min_length' => CCK_PHONE_PHONE_MIN_LENGTH, +++- '%max_length' => CCK_PHONE_PHONE_MAX_LENGTH, +++- '%ext_input' => check_plain($ext_input), +++- '%ext_max_length' => CCK_PHONE_EXTENSION_MAX_LENGTH, +++- ); +++- +++- // Only allow digit, dash, space and bracket +++- if (!_cck_phone_valid_input($phone_input, $ext_input)) { +++- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); +++- if ($field['enable_extension'] && $ext_input != '') { +++- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); +++- } +++- +++- form_set_error($field['field_name'], $error); +++- } +++- else { +++- if (!$field['all_country_codes']) { +++- if (!_cck_phone_valid_cc_input($field['country_selection'], $countrycode)) { +++- $error = t('Invalid country code "%countrycode" submitted.', $error_params); +++- form_set_error($field['field_name'], $error); +++- } +++- } +++- // Generic number validation +++- if (!cck_phone_validate_number($countrycode, $phone_input, $ext_input)) { +++- $error = t('Phone number must be %min_length-%max_length digits only.', $error_params); +++- if ($field['enable_extension'] && $ext_input != '') { +++- $error .= '
'. t('Phone extension must be less than %ext_max_length digits.', $error_params); +++- } +++- +++- form_set_error($field['field_name'], $error); +++- } +++- // Country level validation if enabled +++- elseif ($field['enable_custom_country'] != 0 || is_null($field['enable_custom_country']) || !isset($field['enable_custom_country'])) { +++- $custom_cc = _cck_phone_custom_cc(); +++- +++- if (isset($custom_cc[$countrycode])) { +++- $validate_function = $countrycode . '_validate_number'; +++- +++- if (function_exists($validate_function)) { +++- $error = ''; +++- if (!$validate_function($phone_input, $ext_input, $error)) { +++- form_set_error($field['field_name'], t($error, $error_params)); +++- } +++- } +++- } +++- } +++- } +++- } +++-} +++- +++-function _cck_phone_process(&$item, $delta = 0, $field, $node) { +++- $widget = $field['widget']['default_value'][$delta]; +++- // Clean up the phone number. +++- $item['number'] = cck_phone_clean_number($item['number']); +++- $item['extension'] = cck_phone_clean_number($item['extension']); +++- +++- // Don't save an invalid default value. +++- if ((isset($widget['number']) && $item['number'] == $widget['number']) && (isset($widget['country_codes']) && $item['country_codes'] == $widget['country_codes']) && is_object($node)) { +++- if (!cck_phone_validate_number($item['country_codes'], $item['number'], $item['extension'])) { +++- unset($item['number']); +++- unset($item['country_codes']); +++- unset($item['extension']); +++- } +++- } +++-} +++- +++-/** +++- * Cleanup user-entered values for a phone number field according to field settings. +++- * +++- * @param $item +++- * A single phone number item, usually containing number and country code. +++- * @param $delta +++- * The delta value if this field is one of multiple fields. +++- * @param $field +++- * The CCK field definition. +++- * @param $node +++- * The node containing this phone number. +++- */ +++-function _cck_phone_sanitize(&$item, $delta, &$field, &$node) { +++- if (!empty($item['number'])) { +++- $cc = $item['country_codes']; +++- $item['number'] = cck_phone_clean_number($item['number']); +++- +++- $custom_cc = _cck_phone_custom_cc(); +++- if (isset($custom_cc[$cc])) { +++- $function = $cc . '_sanitize_number'; +++- +++- if (function_exists($function)) { +++- $function($item['number']); +++- } +++- } +++- } +++- +++- if ($field['enable_extension']) { +++- $item['extension'] = cck_phone_clean_number($item['extension']); +++- } +++- else { +++- unset($item['extension']); +++- } +++- +++- if ($field['enable_mobile'] && preg_match(CCK_PHONE_MOBILE_AGENT, drupal_strtolower($_SERVER['HTTP_USER_AGENT']))) { +++- $item['mobile_output'] = TRUE; +++- } +++-} +++- +++- +++-/** +++- * Implementation of hook_widget_info(). +++- */ +++-function cck_phone_widget_info() { +++- return array( +++- 'phone_number' => array( +++- 'label' => t('Phone number'), +++- 'field types' => array('phone_number'), +++- 'multiple values' => CONTENT_HANDLE_CORE, +++- ), +++- ); +++-} +++- +++-/** +++- * Implementation of hook_widget_settings(). +++- */ +++-function cck_phone_widget_settings($op, $widget) { +++- switch ($op) { +++- case 'form': +++- $form = array(); +++- $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : CCK_PHONE_PHONE_MAX_LENGTH; +++- $form['input']['size'] = array( +++- '#type' => 'textfield', +++- '#title' => t('Size of phone number textfield'), +++- '#default_value' => $size, +++- '#element_validate' => array('_element_validate_integer_positive'), +++- '#required' => TRUE, +++- '#description' => t('International number is maximum 15 digits with additional country code, default is %length.', array('%length' => CCK_PHONE_PHONE_MAX_LENGTH)), +++- ); +++- return $form; +++- +++- case 'save': +++- return array('size'); +++- } +++-} +++- +++-/** +++- * Implementation of hook_widget(). +++- */ +++-function cck_phone_widget(&$form, &$form_state, $field, $items, $delta = 0) { +++- $element = array( +++- '#type' => $field['widget']['type'], +++- '#default_value' => isset($items[$delta]) ? $items[$delta] : '', +++- '#title' => $field['widget']['label'], +++- '#weight' => $field['widget']['weight'], +++- '#description' => $field['widget']['description'], +++- '#required' => $field['required'], +++- '#field' => $field, +++- ); +++- return $element; +++-} +++- +++-/** +++- * Implementation of hook_content_is_empty(). +++- */ +++-function cck_phone_content_is_empty($item, $field) { +++- if (empty($item['number'])) { +++- return TRUE; +++- } +++- return FALSE; +++-} +++- +++-/** +++- * Implementation of FAPI hook_elements(). +++- */ +++-function cck_phone_elements() { +++- return array( +++- 'phone_number' => array( +++- '#input' => TRUE, +++- '#process' => array('cck_phone_process'), +++- '#autocomplete_path' => FALSE, +++- ), +++- ); +++-} +++- +++-/** +++- * FAPI theme for an individual phone number elements. +++- * +++- * The phone number is already rendered by the themes and the html +++- * output lives in $element['#children']. Override this theme to +++- * make custom changes to the output. +++- * +++- * $element['#title'] is the field title +++- * $element['#field_name'] contains the field name +++- * $element['#delta''] is the position of this element in the group +++- * $element['number] is the phone number +++- * $element['country_codes'] is the country code +++- */ +++-function theme_phone_number($element) { +++- drupal_add_css(drupal_get_path('module', 'cck_phone') .'/cck_phone.css'); +++- +++- // Prefix single value phone number fields with the name of the field. +++-// if (empty($element['#field']['multiple'])) { +++-// if (isset($element['number']) && isset($element['country_codes'])) { +++-// $element['number']['#title'] = $element['#title'] .' '. $element['number']['#title']; +++-// $element['country_codes']['#title'] = $element['#title'] .' '. $element['country_codes']['#title']; +++-// } +++-// elseif ($element['number']) { +++-// $element['number']['#title'] = $element['#title']; +++-// } +++-// } +++- +++- $output = ''; +++- +++- $output = '
*' : ''; +++- +++- if (!empty($element['#title'])) { +++- $title = $element['#title']; +++- if (!empty($element['number']['#id'])) { +++- $output .= ' \n"; +++- } +++- else { +++- $output .= ' \n"; +++- } +++- } +++- +++- $output .= '
'; +++- if (isset($element['number'])) { +++- $output .= '
'. theme('textfield', $element['number']) .'
'; +++- } +++- if (isset($element['extension'])) { +++- $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : ''; +++- $output .= '
'. $prefix . theme('textfield', $element['extension']) .'
'; +++- } +++- $output .= '
'. theme('select', $element['country_codes']) .'
'; +++- $output .= '
'; +++- +++- return $output; +++-} +++- +++-/** +++- * Process an individual element. +++- */ +++-function cck_phone_process($element, $edit, $form_state, $form) { +++- $field_name = $element['#field_name']; +++- $field = $form['#field_info'][$field_name]; +++- $field_key = $element['#columns'][0]; +++- $delta = $element['#delta']; +++- +++- $element['number'] = array( +++- '#type' => 'textfield', +++- '#maxlength' => CCK_PHONE_PHONE_MAX_LENGTH, +++- '#size' => CCK_PHONE_PHONE_MAX_LENGTH, +++-// '#title' => t('Number'), +++- '#description' => $element['#description'], +++- '#required' => ($delta == 0 && $field['number'] !== 'optional') ? $element['#required'] : FALSE, +++- '#default_value' => isset($element['#value']['number']) ? $element['#value']['number'] : NULL, +++- ); +++- +++- if ($field['enable_extension']) { +++- $element['extension'] = array( +++- '#type' => 'textfield', +++- '#maxlength' => CCK_PHONE_EXTENSION_MAX_LENGTH, +++- '#size' => CCK_PHONE_EXTENSION_MAX_LENGTH, +++-// '#title' => t('ext'), +++- '#required' => FALSE, +++- '#default_value' => isset($element['#value']['extension']) ? $element['#value']['extension'] : NULL, +++- '#prefix' => '
'. t('ext') .'
', +++- ); +++- } +++- +++- $element['country_codes'] = array( +++- '#type' => 'select', +++-// '#title' => 'Country code', +++- '#default_value' => ($element['#value']['number'] != '' && isset($element['#value']['country_codes'])) ? $element['#value']['country_codes'] : (isset($field['default_country']) ? $field['default_country'] : NULL), +++- ); +++- if ($field['all_country_codes']) { +++- $element['country_codes']['#options'] = _cck_phone_cc_options(); +++- } +++- else { +++- $element['country_codes']['#options'] = _cck_phone_cc_options(FALSE, $field['country_selection']); +++- } +++- +++- return $element; +++-} +++- +++-/** +++- * Strip number of space, hash, dash, bracket, etc leaving digit only. +++- * +++- * @param string $number +++- * @return string Returns digit only phone number. +++- */ +++-function cck_phone_clean_number($number) { +++- // Remove none numeric characters +++- $number = preg_replace('/[^0-9]/', '', $number); +++- +++- return $number; +++-} +++- +++-/** +++- * Generic validation for Phone Number. +++- * +++- * @param string $countrycode +++- * @param string $number +++- * @return boolean Returns boolean FALSE if the phone number is not valid. +++- */ +++-function cck_phone_validate_number($countrycode, $number, $ext = '') { +++- // We don't want to worry about separators +++- $number = cck_phone_clean_number($number); +++- if ($number !== '' && drupal_strlen($number) > CCK_PHONE_PHONE_MAX_LENGTH) { +++- return FALSE; +++- } +++- +++- $ext = cck_phone_clean_number($ext); +++- if ($ext !== '' && drupal_strlen($ext) > CCK_PHONE_EXTENSION_MAX_LENGTH) { +++- return FALSE; +++- } +++- +++- return TRUE; +++-} +++- +++- +++-/* ------ Token ------ */ +++- +++-/** +++- * Implementation of hook_token_list(). +++- */ +++-function cck_phone_token_list($type = 'all') { +++- if ($type == 'field' || $type == 'all') { +++- $tokens = array(); +++- +++- $tokens['cck_phone']['number'] = t('Phone number'); +++- $tokens['cck_phone']['country_codes'] = t('Country code'); +++- $tokens['cck_phone']['extension'] = t('Extension'); +++- +++- return $tokens; +++- } +++-} +++- +++-/** +++- * Implementation of hook_token_values(). +++- */ +++-function cck_phone_token_values($type, $object = NULL, $options = array()) { +++- if ($type == 'field') { +++- $item = $object[0]; +++- +++- $tokens['number'] = $item['number']; +++- $tokens['country_codes'] = $item['country_codes']; +++- $tokens['cck_phone']['extension'] = $item['extension']; +++- +++- return $tokens; +++- } +++-} ++++} +++\ No newline at end of file +++Index: includes/phone.ca.inc +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.ca.inc,v +++retrieving revision 1.1 +++diff -u -r1.1 phone.ca.inc +++--- includes/phone.ca.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++++ includes/phone.ca.inc 24 Jul 2010 06:02:20 -0000 +++@@ -7,23 +7,25 @@ +++ */ +++ +++ /** +++- * Verifies that $number is a valid ten-digit North American phone number. ++++ * Validate country level phone number. +++ * +++ * @param $number +++- * Digits only value. +++- * @param $ext +++- * Digits only value. ++++ * Digits only phone number value. ++++ * @param $subaddress ++++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++++ * Reference: http://tools.ietf.org/html/rfc2806. +++ * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number ++++ * Error message that will be displayed to user. ++++ * @param $phone_type ++++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++++ * Pager, BBS, Modem, Car, ISDN, PCS) +++ * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * TRUE if it is a valid phone number for this country, FALSE otherwise. +++ */ +++-function ca_validate_number($number, $ext = '', &$error) { +++- return us_validate_number($number, $ext = '', &$error); ++++function ca_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); ++++ return us_validate_number($number, $subaddress, $error, $phone_type); +++ } +++ +++ /** +++@@ -33,43 +35,17 @@ +++ * A single phone number item. +++ */ +++ function ca_sanitize_number(&$number) { ++++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); +++ us_sanitize_number($number); +++ } +++ +++ /** +++ * Default formatter for international phone number. +++ * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++- */ +++-function ca_formatter_default($element) { +++- return us_formatter_default($element); +++-} +++- +++-/** +++- * Local formatter for local phone number. +++- * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * @param $number ++++ * Phone number. +++ */ +++-function ca_formatter_local($element) { +++- return us_formatter_local($element); ++++function ca_formatter_default($number) { ++++ module_load_include('inc', 'cck_phone', 'includes/phone.us'); ++++ return us_formatter_default($number); +++ } +++\ No newline at end of file +++Index: includes/phone.gb.inc +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.gb.inc,v +++retrieving revision 1.1 +++diff -u -r1.1 phone.gb.inc +++--- includes/phone.gb.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++++ includes/phone.gb.inc 24 Jul 2010 07:12:33 -0000 +++@@ -25,29 +25,27 @@ +++ * Validate country level phone number. +++ * +++ * @param $number +++- * Digits only value. +++- * @param $ext +++- * Digits only value. ++++ * Digits only phone number value. ++++ * @param $subaddress ++++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++++ * Reference: http://tools.ietf.org/html/rfc2806. +++ * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number ++++ * Error message that will be displayed to user. ++++ * @param $phone_type ++++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++++ * Pager, BBS, Modem, Car, ISDN, PCS) +++ * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * TRUE if it is a valid phone number for this country, FALSE otherwise. +++ */ +++-function gb_validate_number($number, $ext = '', &$error) { +++- // We don't want to worry about separators +++- $number = cck_phone_clean_number($number); +++- +++- if (preg_match(_uk_phone_rules(), $number)) { +++- return TRUE; ++++function gb_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++++ if (!empty($number)) { ++++ if (preg_match(_uk_phone_rules(), $number)) { ++++ return TRUE; ++++ } ++++ $error = t('"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "29 9999 9999", with optional leading "0"', array('%phone_input' => $number)); ++++ return FALSE; +++ } +++- +++- // t() is no needed +++- $error = '"%phone_input" is not a valid United Kingdom phone number, it should be 10 digits number like "99 9999 9999", with optional leading "0"'; +++- return FALSE; +++ } +++ +++ /** +++@@ -64,58 +62,16 @@ +++ /** +++ * Default formatter for international phone number. +++ * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++- */ +++-function gb_formatter_default($element) { +++- $item = $element['#item']; +++- +++- // Display a global phone number with country code. +++- $cc = cck_phone_countrycodes($item['country_codes']); +++- +++- $result = preg_match(_uk_phone_rules, $item['number'], $matches); +++- +++- if ($result) { +++- // output as +44 AA BBBB CCCC, +44 AAA BBB CCCC or +44 AAAA BBB CCC +++- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++- } +++- +++- return $phone; +++-} +++- +++- +++-/** +++- * Local formatter for local phone number. +++- * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * @param $number ++++ * Phone number. +++ */ +++-function gb_formatter_local($element) { +++- // Display a local phone number without country code. +++- $result = preg_match(_uk_phone_rules, $item['number'], $matches); ++++function gb_formatter_default($number) { ++++ $result = preg_match(_uk_phone_rules(), $number, $matches); +++ +++ if ($result) { +++- // output as 0AA BBBB CCCC, 0AAA BBB CCCC or 0AAAA BBB CCC +++- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++++ // output as AA BBBB CCCC, AAA BBB CCCC or AAAA BBB CCC ++++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++ } +++ +++ return $phone; +++-} ++++} +++\ No newline at end of file +++Index: includes/phone.my.inc +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.my.inc,v +++retrieving revision 1.1 +++diff -u -r1.1 phone.my.inc +++--- includes/phone.my.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++++ includes/phone.my.inc 24 Jul 2010 07:08:18 -0000 +++@@ -45,78 +45,64 @@ +++ } +++ +++ /** +++- * Verifies that $number is a valid Malaysia phone number. ++++ * Validate country level phone number. +++ * +++ * @param $number +++- * Digits only value. +++- * @param $ext +++- * Digits only value. ++++ * Digits only phone number value. ++++ * @param $subaddress ++++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++++ * Reference: http://tools.ietf.org/html/rfc2806. +++ * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number ++++ * Error message that will be displayed to user. ++++ * @param $phone_type ++++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++++ * Pager, BBS, Modem, Car, ISDN, PCS) +++ * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * TRUE if it is a valid phone number for this country, FALSE otherwise. +++ */ +++-function my_validate_number($number, $ext = '', &$error) { +++- // We don't want to worry about separators +++- $number = cck_phone_clean_number($number); +++- +++- foreach (_my_phone_rules() as $rule) { +++- // define regular expression +++- $regex = '/^ +++- ([0]*) # an optional 0 +++- ('. $rule[0] .') # area code +++- \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] +++- $/x'; +++- +++- $result = preg_match($regex, $number, $matches); +++- +++- if ($result) { +++- return TRUE; ++++function my_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++++ if (!empty($number)) { ++++ foreach (_my_phone_rules() as $rule) { ++++ // define regular expression ++++ $regex = '/^ ++++ ([0]*) # an optional 0 ++++ ('. $rule[0] .') # area code ++++ \d{'. $rule[1] .'} # local number within length $rule[1] & $rule[2] ++++ $/x'; ++++ ++++ $result = preg_match($regex, $number, $matches); ++++ ++++ if ($result) { ++++ return TRUE; ++++ } +++ } ++++ $error = t('"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.', array('%phone_input' => $number)); ++++ return FALSE; +++ } +++- +++- // t() is no needed +++- $error = '"%phone_input" is not a valid Malaysia phone number, it should be 9-10 digits number like "03-2222 2222", "0" is optional and will be removed.'; +++- return FALSE; +++ } +++ +++ /** +++- * Cleanup user-entered values for a phone number field for saving to DB. ++++ * Cleanup user-entered values for a phone number field for storing to DB. +++ * +++ * @param $number +++ * A single phone number item. ++++ * @param $href ++++ * Valid number (numeric and + charaters only) placed at ++++ * href="tel:;ext=123" of anchor tag. +++ */ +++ function my_sanitize_number(&$number) { +++ // Remove trunk prefix '0' +++- +++ $number = preg_replace('/^([0]*)/', '', $number); +++ } +++ +++ /** +++ * Default formatter for international phone number. +++ * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * @param $number ++++ * Phone number. +++ */ +++-function my_formatter_default($element) { +++- $item = $element['#item']; +++- +++- // Display a global phone number with country code. +++- $cc = cck_phone_countrycodes($item['country_codes']); +++- ++++function my_formatter_default($number) { +++ // Format the phone number however you like, this is the default +++ foreach (_my_phone_rules() as $rule) { +++ // define regular expression +++@@ -125,55 +111,14 @@ +++ (\d{3,4}) +++ (\d{4}) +++ $/x'; +++- +++- $result = preg_match($regex, $item['number'], $matches); ++++ $result = preg_match($regex, $number, $matches); +++ +++ if ($result) { +++- // output as +60A-BBB CCCC or +60A-BBBB CCCC +++- $phone = $cc['code'] . $matches[1] .'-'. $matches[2] .' '. $matches[3]; ++++ // output as A-BBB CCCC ++++ $phone = $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++ +++ continue; +++ } +++ } +++- +++- return $phone . $ext; +++-} +++- +++-/** +++- * Local formatter for local phone number. +++- * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++- */ +++-function my_formatter_local($element) { +++- // Display a local phone number without country code. +++- $phone = $element['#item']['number']; +++- +++- foreach (_my_phone_rules() as $rule) { +++- // define regular expression +++- $regex = '/^ +++- ('. $rule[0] .') # area code +++- (\d{3,4}) +++- (\d{4}) +++- $/x'; +++- +++- $result = preg_match($regex, $phone, $matches); +++- +++- if ($result) { +++- // output as 0A-BBB CCCC or 0A-BBBB CCCC +++- $phone = '0'. $matches[1] .'-'. $matches[2] .' '. $matches[3]; +++- continue; +++- } +++- } +++- +++ return $phone; +++-} ++++} +++\ No newline at end of file +++Index: includes/phone.us.inc +++=================================================================== +++RCS file: /cvs/drupal/contributions/modules/cck_phone/includes/phone.us.inc,v +++retrieving revision 1.1 +++diff -u -r1.1 phone.us.inc +++--- includes/phone.us.inc 8 Jul 2010 11:22:37 -0000 1.1 ++++++ includes/phone.us.inc 24 Jul 2010 06:51:51 -0000 +++@@ -7,48 +7,45 @@ +++ */ +++ +++ /** +++- * Verifies that $number is a valid ten-digit North American phone number. ++++ * Validate country level phone number. +++ * +++ * @param $number +++- * Digits only value. +++- * @param $ext +++- * Digits only value. ++++ * Digits only phone number value. ++++ * @param $subaddress ++++ * Subaddress value for telephone/fax's extension number, ISDN subaddress, ++++ * fax's T33 subaddress, modem's parameters/recommended parameters. ++++ * Reference: http://tools.ietf.org/html/rfc2806. +++ * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number ++++ * Error message that will be displayed to user. ++++ * @param $phone_type ++++ * Nature of the phone (Voice, Home, Msg, Work, Pref, Fax, Cell, Video, ++++ * Pager, BBS, Modem, Car, ISDN, PCS) +++ * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * TRUE if it is a valid phone number for this country, FALSE otherwise. +++ */ +++-function us_validate_number($number, $ext = '', &$error) { +++- // Don't need to check for extension because it has been checked by generic validation as all digits, unless has special format/requirements +++- // We don't want to worry about separators +++- $number = cck_phone_clean_number($number); +++- +++- // define regular expression +++- $regex = '/^ +++- ([1]*) # an optional 1 +++- [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) +++- [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) +++- \d{4} # 4-digit line number +++- $/x'; +++- +++- $result = preg_match($regex, $number, $matches); +++- +++- if ($result && $matches[1] == '') { +++- return TRUE; +++- } +++- elseif ($result && $matches[1] == '1') { +++- // t() is no needed +++- $error = 'Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'; +++- return FALSE; +++- } +++- else { +++- // t() is no needed +++- $error = '"%phone_input" is not a valid North American phone number, it should be 10 digits number like "999 999 9999"'; +++- return FALSE; ++++function us_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') { ++++ if (!empty($number)) { ++++ // Define regular expression ++++ $regex = '/^ ++++ ([1]*) # an optional 1 ++++ [2-9][0-8]\d # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) ++++ [2-9]\d{2} # 3-digit prefix (cannot start with 0 or 1) ++++ \d{4} # 4-digit line number ++++ $/x'; ++++ ++++ $result = preg_match($regex, $number, $matches); ++++ ++++ if ($result && $matches[1] == '') { ++++ return TRUE; ++++ } ++++ elseif ($result && $matches[1] == '1') { ++++ $error = t('Please enter a 10 digits North American phone number like "999 999 9999", without the country code "1" or "+1"'); ++++ return FALSE; ++++ } ++++ else { ++++ $error = t('%phone_input is not a valid North American phone number, it should be 10 digits number like "989 999 9999"', array('%phone_input' => $number)); ++++ return FALSE; ++++ } +++ } +++ } +++ +++@@ -68,25 +65,10 @@ +++ /** +++ * Default formatter for international phone number. +++ * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. ++++ * @param $number ++++ * Phone number. +++ */ +++-function us_formatter_default($element) { +++- $item = $element['#item']; +++- $phone = ''; +++- +++- // Display a global phone number with country code. +++- $cc = cck_phone_countrycodes($item['country_codes']); +++- ++++function us_formatter_default($number) { +++ // Format the phone number however you like, this is the default +++ // define regular expression +++ $regex = '/^ +++@@ -95,43 +77,7 @@ +++ (\d{4}) # 4-digit line number +++ /x'; +++ +++- $result = preg_match($regex, $item['number'], $matches); +++- +++- if ($result) { +++- // output as +1 (AAA) BBB CCCC +++- $phone = $cc['code'] .' ('. $matches[1] .') '. $matches[2] .' '. $matches[3]; +++- } +++- +++- return $phone . $ext; +++-} +++- +++-/** +++- * Local formatter for local phone number. +++- * +++- * @param $element +++- * $element['#item']['country_codes']: alpha-2 country code +++- * $element['#item']['number']: phone number +++- * @param $error +++- * The error message to shown to user. +++- * Available parameters to use in the error message are +++- * - "%countrycode": the alpha-2 CC +++- * - "%phone_input": the original number input by user (could be invalid) +++- * - "%max_length": allowed maximum length of the phone number +++- * @return boolean +++- * TRUE if it is a valid phone number for that country, FALSE otherwise. +++- */ +++-function us_formatter_local($element) { +++- $item = $element['#item']; +++- $phone = ''; +++- +++- // Display a local phone number without country code. +++- $regex = '/^ +++- ([2-9][0-8]\d) # area code (Allowed range of [2-9] for the first digit, [0-8] for the second, and [0-9] for the third digit) +++- ([2-9]\d{2}) # 3-digit prefix (cannot start with 0 or 1) +++- (\d{4}) # 4-digit line number +++- /x'; +++- +++- $result = preg_match($regex, $item['number'], $matches); ++++ $result = preg_match($regex, $number, $matches); +++ +++ if ($result) { +++ // output as (AAA) BBB CCCC +++@@ -139,4 +85,4 @@ +++ } +++ +++ return $phone; +++-} ++++} +++\ No newline at end of file +++--- cck_phone_countrycodes.inc.tortoise.removed ++++++ cck_phone_countrycodes.inc.tortoise.removed +++@@ -0,0 +1,266 @@ ++++ array('country' => 'Afghanistan', 'code' => '+93'), ++++ 'al' => array('country' => 'Albania', 'code' => '+355'), ++++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), ++++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), ++++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), ++++ 'ao' => array('country' => 'Angola', 'code' => '+244'), ++++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), ++++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), ++++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), ++++ 'am' => array('country' => 'Armenia', 'code' => '+374'), ++++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), ++++ 'au' => array('country' => 'Australia', 'code' => '+61'), ++++ 'at' => array('country' => 'Austria', 'code' => '+43'), ++++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), ++++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), ++++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), ++++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), ++++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), ++++ 'by' => array('country' => 'Belarus', 'code' => '+375'), ++++ 'be' => array('country' => 'Belgium', 'code' => '+32'), ++++ 'bz' => array('country' => 'Belize', 'code' => '+501'), ++++ 'bj' => array('country' => 'Benin', 'code' => '+229'), ++++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), ++++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), ++++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), ++++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), ++++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), ++++ 'br' => array('country' => 'Brazil', 'code' => '+55'), ++++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), ++++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), ++++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), ++++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), ++++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), ++++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), ++++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), ++++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), ++++ 'ca' => array('country' => 'Canada', 'code' => '+1'), ++++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), ++++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), ++++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), ++++ 'td' => array('country' => 'Chad', 'code' => '+235'), ++++ 'cl' => array('country' => 'Chile', 'code' => '+56'), ++++ 'cn' => array('country' => 'China', 'code' => '+86'), ++++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), ++++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), ++++ 'co' => array('country' => 'Colombia', 'code' => '+57'), ++++ 'km' => array('country' => 'Comoros', 'code' => '+269'), ++++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), ++++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), ++++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), ++++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), ++++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), ++++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), ++++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), ++++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), ++++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), ++++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), ++++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), ++++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), ++++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), ++++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), ++++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), ++++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), ++++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), ++++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), ++++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), ++++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), ++++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), ++++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), ++++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), ++++ 'fi' => array('country' => 'Finland', 'code' => '+358'), ++++ 'fr' => array('country' => 'France', 'code' => '+33'), ++++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), ++++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), ++++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), ++++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), ++++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), ++++ 'de' => array('country' => 'Germany', 'code' => '+49'), ++++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), ++++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), ++++ 'gr' => array('country' => 'Greece', 'code' => '+30'), ++++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), ++++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), ++++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), ++++ 'gu' => array('country' => 'Guam', 'code' => '+1'), ++++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), ++++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), ++++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), ++++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), ++++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), ++++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), ++++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), ++++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), ++++ 'is' => array('country' => 'Iceland', 'code' => '+354'), ++++ 'in' => array('country' => 'India', 'code' => '+91'), ++++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), ++++ 'ir' => array('country' => 'Iran', 'code' => '+98'), ++++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), ++++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), ++++ 'il' => array('country' => 'Israel', 'code' => '+972'), ++++ 'it' => array('country' => 'Italy', 'code' => '+39'), ++++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), ++++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), ++++ 'jp' => array('country' => 'Japan', 'code' => '+81'), ++++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), ++++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), ++++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), ++++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), ++++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), ++++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), ++++ 'la' => array('country' => 'Laos', 'code' => '+856'), ++++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), ++++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), ++++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), ++++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), ++++ 'ly' => array('country' => 'Libya', 'code' => '+218'), ++++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), ++++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), ++++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), ++++ 'mo' => array('country' => 'Macau', 'code' => '+853'), ++++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), ++++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), ++++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), ++++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), ++++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), ++++ 'ml' => array('country' => 'Mali', 'code' => '+223'), ++++ 'mt' => array('country' => 'Malta', 'code' => '+356'), ++++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), ++++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), ++++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), ++++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), ++++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), ++++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), ++++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), ++++ 'md' => array('country' => 'Moldova', 'code' => '+373'), ++++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), ++++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), ++++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), ++++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), ++++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), ++++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), ++++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), ++++ 'na' => array('country' => 'Namibia', 'code' => '+264'), ++++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), ++++ 'np' => array('country' => 'Nepal', 'code' => '+977'), ++++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), ++++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), ++++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), ++++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), ++++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), ++++ 'ne' => array('country' => 'Niger', 'code' => '+227'), ++++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), ++++ 'nu' => array('country' => 'Niue', 'code' => '+683'), ++++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), ++++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), ++++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), ++++ 'no' => array('country' => 'Norway', 'code' => '+47'), ++++ 'om' => array('country' => 'Oman', 'code' => '+968'), ++++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), ++++ 'pw' => array('country' => 'Palau', 'code' => '+680'), ++++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), ++++ 'pa' => array('country' => 'Panama', 'code' => '+507'), ++++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), ++++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), ++++ 'pe' => array('country' => 'Peru', 'code' => '+51'), ++++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), ++++ 'pl' => array('country' => 'Poland', 'code' => '+48'), ++++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), ++++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), ++++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), ++++ 'ro' => array('country' => 'Romania', 'code' => '+40'), ++++ 'ru' => array('country' => 'Russia', 'code' => '+7'), ++++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), ++++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), ++++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), ++++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), ++++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), ++++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), ++++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), ++++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), ++++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), ++++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), ++++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), ++++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), ++++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), ++++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), ++++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), ++++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), ++++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), ++++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), ++++ 'so' => array('country' => 'Somalia', 'code' => '+252'), ++++ 'za' => array('country' => 'South Africa', 'code' => '+27'), ++++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), ++++ 'es' => array('country' => 'Spain', 'code' => '+34'), ++++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), ++++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), ++++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), ++++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), ++++ 'se' => array('country' => 'Sweden', 'code' => '+46'), ++++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), ++++ 'sy' => array('country' => 'Syria', 'code' => '+963'), ++++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), ++++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), ++++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), ++++ 'th' => array('country' => 'Thailand', 'code' => '+66'), ++++ 'tg' => array('country' => 'Togo', 'code' => '+228'), ++++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), ++++ 'to' => array('country' => 'Tonga', 'code' => '+676'), ++++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), ++++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), ++++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), ++++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), ++++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), ++++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), ++++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), ++++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), ++++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), ++++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), ++++ 'us' => array('country' => 'United States', 'code' => '+1'), ++++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), ++++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), ++++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), ++++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), ++++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), ++++ 've' => array('country' => 'Venezuela', 'code' => '+58'), ++++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), ++++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), ++++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), ++++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), ++++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), ++++ ); ++++ ++++ if (is_null($cc)) { ++++ return $country_code; ++++ } ++++ elseif (isset($country_code[$cc])) { ++++ return $country_code[$cc]; ++++ } ++++ ++++ return FALSE; ++++} +++ +++--- css/cck_phone.css ++++++ css/cck_phone.css +++@@ -0,0 +1,35 @@ ++++/* $Id: cck_phone.css,v 1.2 2010/07/12 09:54:52 ckng Exp $ */ ++++.cck-phone-field .form-item { ++++ margin: 0; ++++} ++++ ++++.cck-phone-column { ++++ float: left; ++++} ++++.cck-phone-field-phone { ++++ width: 15em; ++++} ++++.cck-phone-field-cc { ++++ width: 25em; ++++} ++++ ++++.cck-phone-field-ext { ++++ width: 9em; ++++} ++++.cck-phone-extension { ++++ float: left; ++++ margin: 0 .5em; ++++} ++++.cck-phone-field-ext .form-item { ++++ float: left; ++++} ++++ ++++.cck-phone-settings .form-checkboxes .form-item { ++++ float: left; ++++ width: 33%; ++++} ++++ ++++.cck-phone-settings .cck-phone-default-country { ++++ background: #eee; ++++ font-weight: bold; ++++} +++ +++--- includes/cc.template.php ++++++ includes/cc.template.php +++@@ -0,0 +1,70 @@ ++++ $subaddress)); ++++ return FALSE; ++++ } ++++ // Assign $number_error as FALSE if $number is not valid ++++ if (!empty($number) && $number_error) { ++++ $error = t('%phone_input is not a valid phone number, it should be 10 digits number like "999 999 9999"', array('%phone_input' => $number)); ++++ return FALSE; ++++ } ++++ return TRUE; ++++} ++++ ++++ ++++/** ++++ * Cleanup user-entered values for a phone number field for storing to DB. ++++ * ++++ * @param $number ++++ * A single phone number item. ++++ */ ++++function CC_sanitize_number(&$number) { ++++ // your cleanup like removing trunk prefix ++++ $number = preg_replace('/^([0]*)/', '', $number); ++++} ++++ ++++ ++++/** ++++ * Default formatter for international phone number. ++++ * ++++ * @param $number ++++ * Phone number. ++++ */ ++++function CC_formatter_default($number) { ++++ // Format the phone number and its area code into human readable format ++++ $phone = $number; ++++ ++++ return $phone; ++++} +++ +++--- includes/cck_phone_countrycodes.inc ++++++ includes/cck_phone_countrycodes.inc +++@@ -0,0 +1,266 @@ ++++ array('country' => 'Afghanistan', 'code' => '+93'), ++++ 'al' => array('country' => 'Albania', 'code' => '+355'), ++++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), ++++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), ++++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), ++++ 'ao' => array('country' => 'Angola', 'code' => '+244'), ++++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), ++++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), ++++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), ++++ 'am' => array('country' => 'Armenia', 'code' => '+374'), ++++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), ++++ 'au' => array('country' => 'Australia', 'code' => '+61'), ++++ 'at' => array('country' => 'Austria', 'code' => '+43'), ++++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), ++++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), ++++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), ++++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), ++++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), ++++ 'by' => array('country' => 'Belarus', 'code' => '+375'), ++++ 'be' => array('country' => 'Belgium', 'code' => '+32'), ++++ 'bz' => array('country' => 'Belize', 'code' => '+501'), ++++ 'bj' => array('country' => 'Benin', 'code' => '+229'), ++++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), ++++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), ++++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), ++++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), ++++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), ++++ 'br' => array('country' => 'Brazil', 'code' => '+55'), ++++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), ++++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), ++++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), ++++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), ++++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), ++++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), ++++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), ++++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), ++++ 'ca' => array('country' => 'Canada', 'code' => '+1'), ++++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), ++++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), ++++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), ++++ 'td' => array('country' => 'Chad', 'code' => '+235'), ++++ 'cl' => array('country' => 'Chile', 'code' => '+56'), ++++ 'cn' => array('country' => 'China', 'code' => '+86'), ++++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), ++++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), ++++ 'co' => array('country' => 'Colombia', 'code' => '+57'), ++++ 'km' => array('country' => 'Comoros', 'code' => '+269'), ++++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), ++++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), ++++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), ++++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), ++++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), ++++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), ++++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), ++++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), ++++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), ++++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), ++++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), ++++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), ++++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), ++++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), ++++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), ++++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), ++++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), ++++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), ++++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), ++++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), ++++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), ++++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), ++++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), ++++ 'fi' => array('country' => 'Finland', 'code' => '+358'), ++++ 'fr' => array('country' => 'France', 'code' => '+33'), ++++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), ++++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), ++++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), ++++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), ++++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), ++++ 'de' => array('country' => 'Germany', 'code' => '+49'), ++++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), ++++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), ++++ 'gr' => array('country' => 'Greece', 'code' => '+30'), ++++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), ++++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), ++++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), ++++ 'gu' => array('country' => 'Guam', 'code' => '+1'), ++++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), ++++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), ++++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), ++++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), ++++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), ++++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), ++++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), ++++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), ++++ 'is' => array('country' => 'Iceland', 'code' => '+354'), ++++ 'in' => array('country' => 'India', 'code' => '+91'), ++++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), ++++ 'ir' => array('country' => 'Iran', 'code' => '+98'), ++++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), ++++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), ++++ 'il' => array('country' => 'Israel', 'code' => '+972'), ++++ 'it' => array('country' => 'Italy', 'code' => '+39'), ++++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), ++++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), ++++ 'jp' => array('country' => 'Japan', 'code' => '+81'), ++++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), ++++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), ++++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), ++++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), ++++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), ++++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), ++++ 'la' => array('country' => 'Laos', 'code' => '+856'), ++++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), ++++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), ++++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), ++++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), ++++ 'ly' => array('country' => 'Libya', 'code' => '+218'), ++++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), ++++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), ++++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), ++++ 'mo' => array('country' => 'Macau', 'code' => '+853'), ++++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), ++++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), ++++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), ++++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), ++++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), ++++ 'ml' => array('country' => 'Mali', 'code' => '+223'), ++++ 'mt' => array('country' => 'Malta', 'code' => '+356'), ++++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), ++++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), ++++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), ++++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), ++++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), ++++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), ++++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), ++++ 'md' => array('country' => 'Moldova', 'code' => '+373'), ++++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), ++++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), ++++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), ++++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), ++++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), ++++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), ++++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), ++++ 'na' => array('country' => 'Namibia', 'code' => '+264'), ++++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), ++++ 'np' => array('country' => 'Nepal', 'code' => '+977'), ++++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), ++++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), ++++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), ++++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), ++++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), ++++ 'ne' => array('country' => 'Niger', 'code' => '+227'), ++++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), ++++ 'nu' => array('country' => 'Niue', 'code' => '+683'), ++++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), ++++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), ++++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), ++++ 'no' => array('country' => 'Norway', 'code' => '+47'), ++++ 'om' => array('country' => 'Oman', 'code' => '+968'), ++++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), ++++ 'pw' => array('country' => 'Palau', 'code' => '+680'), ++++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), ++++ 'pa' => array('country' => 'Panama', 'code' => '+507'), ++++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), ++++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), ++++ 'pe' => array('country' => 'Peru', 'code' => '+51'), ++++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), ++++ 'pl' => array('country' => 'Poland', 'code' => '+48'), ++++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), ++++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), ++++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), ++++ 'ro' => array('country' => 'Romania', 'code' => '+40'), ++++ 'ru' => array('country' => 'Russia', 'code' => '+7'), ++++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), ++++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), ++++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), ++++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), ++++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), ++++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), ++++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), ++++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), ++++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), ++++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), ++++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), ++++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), ++++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), ++++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), ++++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), ++++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), ++++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), ++++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), ++++ 'so' => array('country' => 'Somalia', 'code' => '+252'), ++++ 'za' => array('country' => 'South Africa', 'code' => '+27'), ++++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), ++++ 'es' => array('country' => 'Spain', 'code' => '+34'), ++++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), ++++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), ++++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), ++++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), ++++ 'se' => array('country' => 'Sweden', 'code' => '+46'), ++++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), ++++ 'sy' => array('country' => 'Syria', 'code' => '+963'), ++++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), ++++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), ++++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), ++++ 'th' => array('country' => 'Thailand', 'code' => '+66'), ++++ 'tg' => array('country' => 'Togo', 'code' => '+228'), ++++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), ++++ 'to' => array('country' => 'Tonga', 'code' => '+676'), ++++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), ++++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), ++++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), ++++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), ++++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), ++++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), ++++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), ++++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), ++++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), ++++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), ++++ 'us' => array('country' => 'United States', 'code' => '+1'), ++++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), ++++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), ++++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), ++++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), ++++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), ++++ 've' => array('country' => 'Venezuela', 'code' => '+58'), ++++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), ++++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), ++++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), ++++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), ++++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), ++++ ); ++++ ++++ if (is_null($cc)) { ++++ return $country_code; ++++ } ++++ elseif (isset($country_code[$cc])) { ++++ return $country_code[$cc]; ++++ } ++++ ++++ return FALSE; ++++} +++ +++--- includes/phone.ph.inc ++++++ includes/phone.ph.inc +++@@ -0,0 +1,108 @@ ++++ 12)) { ++++ $error = t('%phone_input is not a valid phone number, it should have at least 8 digits number like "2 999 9999" and maximum of 12 digits like "12345 999 9999".', array('%phone_input' => $number)); ++++ return FALSE; ++++ } ++++ return TRUE; ++++} ++++ ++++/** ++++ * Cleanup user-entered values for a phone number field for storing to DB. ++++ * ++++ * @param $number ++++ * A single phone number item. ++++ */ ++++function ph_sanitize_number(&$number) { ++++ $number = preg_replace('/^([0]*)/', '', $number); ++++} ++++ ++++/** ++++ * Default formatter for international phone number. ++++ * ++++ * @param $number ++++ * Phone number. ++++ */ ++++function ph_formatter_default($number) { ++++ $regex = "/ ++++ # 5 digit area code. ++++ ( ++++ (\d{5}) # capture 5 digit area code ++++ (\d{3}) # capture first set of numbers in the local number ++++ (\d{4}) # capture second set of numbers in the local number ++++ | ++++ # 4 digit area code. ++++ (\d{4}) # capture 4 digit area code ++++ (\d{3}) # capture first set of numbers in the local number ++++ (\d{4}) # capture second set of numbers in the local number ++++ | ++++ # 3 digit area code. ++++ (\d{3}) # capture 3 digit area code ++++ (\d{3}) # capture first set of numbers in the local number ++++ (\d{4}) # capture second set of numbers in the local number ++++ | ++++ # 2 digit area code. ++++ (\d{2}) # capture 2 digit area code ++++ (\d{3}) # capture first set of numbers in the local number ++++ (\d{4}) # capture second set of numbers in the local number ++++ | ++++ # 1 digit area code. ++++ (\d{1}) # capture 1 digit area code ++++ (\d{3}) # capture first set of numbers in the local number ++++ (\d{4}) # capture second set of numbers in the local number ++++ ) ++++ /x"; ++++ ++++ preg_match($regex, $number, $matches); ++++ if (isset($matches[14]) && !empty($matches[14])) { ++++ $area = $matches[14]; ++++ $head_num = $matches[15]; ++++ $tail_num = $matches[16]; ++++ } ++++ elseif (isset($matches[11]) && !empty($matches[11])) { ++++ $area = $matches[11]; ++++ $head_num = $matches[12]; ++++ $tail_num = $matches[13]; ++++ } ++++ elseif (isset($matches[8]) && !empty($matches[8])) { ++++ $area = $matches[8]; ++++ $head_num = $matches[9]; ++++ $tail_num = $matches[10]; ++++ } ++++ elseif (isset($matches[5]) && !empty($matches[5])) { ++++ $area = $matches[5]; ++++ $head_num = $matches[6]; ++++ $tail_num = $matches[7]; ++++ } ++++ else { ++++ $area = $matches[2]; ++++ $head_num = $matches[3]; ++++ $tail_num = $matches[4]; ++++ } ++++ return '(' . $area . ') ' . $head_num . '-' . $tail_num; ++++} +++ +++--- js/cck_phone.manage_field.js ++++++ js/cck_phone.manage_field.js +++@@ -0,0 +1,113 @@ ++++// $Id: cck_phone.js,v 1.2 2010/07/12 09:54:52 ckng Exp $ ++++ ++++Drupal.PhoneNumber = Drupal.PhoneNumber || {}; ++++ ++++/** ++++ * Filters checkboxes based on their label. ++++ * This code is shamelessly taken from checkbox_filter ++++ */ ++++Drupal.PhoneNumber.filter = function() { ++++ var field = $(this); ++++ var checkboxes = $('.form-checkboxes .form-item', field.parent().parent()); ++++ var found = false; ++++ var label = ""; ++++ var option = null; ++++ for (var i = 0; i < checkboxes.length; i++) { ++++ option = checkboxes.eq(i); ++++ label = Drupal.PhoneNumber.trim(option.text()); ++++ if (label.toUpperCase().indexOf(field.val().toUpperCase()) < 0) { ++++ option.hide(); ++++ } else { ++++ option.show(); ++++ } ++++ } ++++} ++++ ++++/** ++++ * Trims whitespace from strings ++++ */ ++++Drupal.PhoneNumber.trim = function(str) { ++++ var str = str.replace(/^\s\s*/, ''), ++++ ws = /\s/, ++++ i = str.length; ++++ while (ws.test(str.charAt(--i))); ++++ return str.slice(0, i + 1); ++++} ++++ ++++/** ++++ * Check/Uncheck all checkboxes ++++ */ ++++Drupal.PhoneNumber.checkall = function(e) { ++++ var field = $(this); ++++ var checkboxes = $('.form-checkboxes .form-item:visible .form-checkbox', field.parent().parent()); ++++ ++++ var checked = (field.text() == Drupal.t('Select all')); ++++ if (checked) { ++++ checkboxes.attr('checked', true); ++++ field.text(Drupal.t('Deselect all')); ++++ } ++++ else { ++++ checkboxes.attr('checked', false); ++++ Drupal.PhoneNumber.checkDefault(); ++++ field.text(Drupal.t('Select all')); ++++ } ++++} ++++ ++++/** ++++ * Country selection should include default country code by default. ++++ */ ++++Drupal.PhoneNumber.checkDefault = function(e) { ++++ var defaultCC = $('#edit-default-country').val(); ++++ var span = $('').append(Drupal.t('Default')); ++++ ++++ if ($('.cck-phone-default-country').find('.form-checkbox').val() == defaultCC) { ++++ $('#edit-country-selection-' + defaultCC) ++++ .attr('checked', 'checked'); ++++ } ++++ else { ++++ $('.cck-phone-default-country') ++++ .removeClass('cck-phone-default-country') ++++ .find('span.default-cc').remove(); ++++ ++++ ++++ $('#edit-country-selection-' + defaultCC) ++++ .attr('checked', 'checked') ++++ .parents('.form-item:first') ++++ .addClass('cck-phone-default-country') ++++ .append(span); ++++ } ++++} ++++ ++++/** ++++ * Attach a filtering textfield to checkboxes. ++++ */ ++++Drupal.behaviors.PhoneNumber = function (context) { ++++ // Toggle collapsible on selection ++++ $('#edit-all-country-codes').change(function() { ++++ if ($(this).attr('checked')) { ++++ $('fieldset.cck-phone-settings').addClass('collapsed'); ++++ } ++++ else { ++++ $('fieldset.cck-phone-settings').removeClass('collapsed'); ++++ } ++++ }); ++++ $('#edit-all-country-codes').trigger('change'); ++++ ++++ // Ensure the new default country is checked ++++ $('#edit-default-country, .cck-phone-settings .form-checkboxes').bind('change', Drupal.PhoneNumber.checkDefault); ++++ $('#edit-default-country').trigger('change'); ++++ $('form#content-field-edit-form').submit(Drupal.PhoneNumber.checkDefault); ++++ ++++ ++++ // Filter for countries ++++ var form = '
' ++++ + ' ' ++++ + ' ' ++++ + '
' ++++ + '
' ++++ + ' ' + Drupal.t('Select all') + '' ++++ + '
'; ++++ $('.cck-phone-settings .form-checkboxes', context).before(form); ++++ $('input.cck-phone-filter').bind('keyup', Drupal.PhoneNumber.filter); ++++ $('a.cck-phone-check').bind('click', Drupal.PhoneNumber.checkall); ++++} +++ +++--- theme/phone-field-view.tpl.php ++++++ theme/phone-field-view.tpl.php +++@@ -0,0 +1,20 @@ ++++ ++++ ++++ ++++ ++++ ++++ +++ +++ ++ ++--- cck_phone_countrycodes.inc.tortoise.removed +++++ cck_phone_countrycodes.inc.tortoise.removed ++@@ -0,0 +1,266 @@ +++ array('country' => 'Afghanistan', 'code' => '+93'), +++ 'al' => array('country' => 'Albania', 'code' => '+355'), +++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), +++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), +++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), +++ 'ao' => array('country' => 'Angola', 'code' => '+244'), +++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), +++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), +++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), +++ 'am' => array('country' => 'Armenia', 'code' => '+374'), +++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), +++ 'au' => array('country' => 'Australia', 'code' => '+61'), +++ 'at' => array('country' => 'Austria', 'code' => '+43'), +++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), +++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), +++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), +++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), +++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), +++ 'by' => array('country' => 'Belarus', 'code' => '+375'), +++ 'be' => array('country' => 'Belgium', 'code' => '+32'), +++ 'bz' => array('country' => 'Belize', 'code' => '+501'), +++ 'bj' => array('country' => 'Benin', 'code' => '+229'), +++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), +++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), +++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), +++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), +++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), +++ 'br' => array('country' => 'Brazil', 'code' => '+55'), +++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), +++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), +++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), +++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), +++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), +++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), +++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), +++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), +++ 'ca' => array('country' => 'Canada', 'code' => '+1'), +++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), +++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), +++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), +++ 'td' => array('country' => 'Chad', 'code' => '+235'), +++ 'cl' => array('country' => 'Chile', 'code' => '+56'), +++ 'cn' => array('country' => 'China', 'code' => '+86'), +++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), +++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), +++ 'co' => array('country' => 'Colombia', 'code' => '+57'), +++ 'km' => array('country' => 'Comoros', 'code' => '+269'), +++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), +++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), +++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), +++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), +++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), +++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), +++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), +++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), +++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), +++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), +++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), +++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), +++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), +++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), +++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), +++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), +++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), +++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), +++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), +++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), +++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), +++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), +++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), +++ 'fi' => array('country' => 'Finland', 'code' => '+358'), +++ 'fr' => array('country' => 'France', 'code' => '+33'), +++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), +++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), +++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), +++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), +++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), +++ 'de' => array('country' => 'Germany', 'code' => '+49'), +++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), +++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), +++ 'gr' => array('country' => 'Greece', 'code' => '+30'), +++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), +++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), +++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), +++ 'gu' => array('country' => 'Guam', 'code' => '+1'), +++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), +++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), +++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), +++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), +++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), +++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), +++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), +++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), +++ 'is' => array('country' => 'Iceland', 'code' => '+354'), +++ 'in' => array('country' => 'India', 'code' => '+91'), +++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), +++ 'ir' => array('country' => 'Iran', 'code' => '+98'), +++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), +++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), +++ 'il' => array('country' => 'Israel', 'code' => '+972'), +++ 'it' => array('country' => 'Italy', 'code' => '+39'), +++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), +++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), +++ 'jp' => array('country' => 'Japan', 'code' => '+81'), +++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), +++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), +++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), +++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), +++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), +++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), +++ 'la' => array('country' => 'Laos', 'code' => '+856'), +++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), +++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), +++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), +++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), +++ 'ly' => array('country' => 'Libya', 'code' => '+218'), +++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), +++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), +++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), +++ 'mo' => array('country' => 'Macau', 'code' => '+853'), +++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), +++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), +++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), +++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), +++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), +++ 'ml' => array('country' => 'Mali', 'code' => '+223'), +++ 'mt' => array('country' => 'Malta', 'code' => '+356'), +++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), +++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), +++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), +++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), +++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), +++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), +++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), +++ 'md' => array('country' => 'Moldova', 'code' => '+373'), +++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), +++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), +++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), +++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), +++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), +++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), +++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), +++ 'na' => array('country' => 'Namibia', 'code' => '+264'), +++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), +++ 'np' => array('country' => 'Nepal', 'code' => '+977'), +++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), +++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), +++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), +++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), +++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), +++ 'ne' => array('country' => 'Niger', 'code' => '+227'), +++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), +++ 'nu' => array('country' => 'Niue', 'code' => '+683'), +++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), +++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), +++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), +++ 'no' => array('country' => 'Norway', 'code' => '+47'), +++ 'om' => array('country' => 'Oman', 'code' => '+968'), +++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), +++ 'pw' => array('country' => 'Palau', 'code' => '+680'), +++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), +++ 'pa' => array('country' => 'Panama', 'code' => '+507'), +++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), +++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), +++ 'pe' => array('country' => 'Peru', 'code' => '+51'), +++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), +++ 'pl' => array('country' => 'Poland', 'code' => '+48'), +++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), +++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), +++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), +++ 'ro' => array('country' => 'Romania', 'code' => '+40'), +++ 'ru' => array('country' => 'Russia', 'code' => '+7'), +++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), +++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), +++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), +++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), +++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), +++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), +++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), +++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), +++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), +++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), +++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), +++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), +++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), +++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), +++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), +++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), +++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), +++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), +++ 'so' => array('country' => 'Somalia', 'code' => '+252'), +++ 'za' => array('country' => 'South Africa', 'code' => '+27'), +++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), +++ 'es' => array('country' => 'Spain', 'code' => '+34'), +++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), +++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), +++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), +++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), +++ 'se' => array('country' => 'Sweden', 'code' => '+46'), +++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), +++ 'sy' => array('country' => 'Syria', 'code' => '+963'), +++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), +++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), +++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), +++ 'th' => array('country' => 'Thailand', 'code' => '+66'), +++ 'tg' => array('country' => 'Togo', 'code' => '+228'), +++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), +++ 'to' => array('country' => 'Tonga', 'code' => '+676'), +++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), +++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), +++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), +++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), +++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), +++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), +++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), +++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), +++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), +++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), +++ 'us' => array('country' => 'United States', 'code' => '+1'), +++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), +++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), +++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), +++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), +++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), +++ 've' => array('country' => 'Venezuela', 'code' => '+58'), +++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), +++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), +++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), +++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), +++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), +++ ); +++ +++ if (is_null($cc)) { +++ return $country_code; +++ } +++ elseif (isset($country_code[$cc])) { +++ return $country_code[$cc]; +++ } +++ +++ return FALSE; +++} ++ ++--- css/cck_phone.css +++++ css/cck_phone.css ++@@ -0,0 +1,35 @@ +++/* $Id: cck_phone.css,v 1.2 2010/07/12 09:54:52 ckng Exp $ */ +++.cck-phone-field .form-item { +++ margin: 0; +++} +++ +++.cck-phone-column { +++ float: left; +++} +++.cck-phone-field-phone { +++ width: 15em; +++} +++.cck-phone-field-cc { +++ width: 25em; +++} +++ +++.cck-phone-field-ext { +++ width: 9em; +++} +++.cck-phone-extension { +++ float: left; +++ margin: 0 .5em; +++} +++.cck-phone-field-ext .form-item { +++ float: left; +++} +++ +++.cck-phone-settings .form-checkboxes .form-item { +++ float: left; +++ width: 33%; +++} +++ +++.cck-phone-settings .cck-phone-default-country { +++ background: #eee; +++ font-weight: bold; +++} ++ ++--- includes/cc.template.php +++++ includes/cc.template.php ++@@ -0,0 +1,70 @@ +++ $subaddress)); +++ return FALSE; +++ } +++ // Assign $number_error as FALSE if $number is not valid +++ if (!empty($number) && $number_error) { +++ $error = t('%phone_input is not a valid phone number, it should be 10 digits number like "999 999 9999"', array('%phone_input' => $number)); +++ return FALSE; +++ } +++ return TRUE; +++} +++ +++ +++/** +++ * Cleanup user-entered values for a phone number field for storing to DB. +++ * +++ * @param $number +++ * A single phone number item. +++ */ +++function CC_sanitize_number(&$number) { +++ // your cleanup like removing trunk prefix +++ $number = preg_replace('/^([0]*)/', '', $number); +++} +++ +++ +++/** +++ * Default formatter for international phone number. +++ * +++ * @param $number +++ * Phone number. +++ */ +++function CC_formatter_default($number) { +++ // Format the phone number and its area code into human readable format +++ $phone = $number; +++ +++ return $phone; +++} ++ ++--- includes/cck_phone_countrycodes.inc +++++ includes/cck_phone_countrycodes.inc ++@@ -0,0 +1,266 @@ +++ array('country' => 'Afghanistan', 'code' => '+93'), +++ 'al' => array('country' => 'Albania', 'code' => '+355'), +++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), +++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), +++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), +++ 'ao' => array('country' => 'Angola', 'code' => '+244'), +++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), +++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), +++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), +++ 'am' => array('country' => 'Armenia', 'code' => '+374'), +++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), +++ 'au' => array('country' => 'Australia', 'code' => '+61'), +++ 'at' => array('country' => 'Austria', 'code' => '+43'), +++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), +++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), +++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), +++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), +++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), +++ 'by' => array('country' => 'Belarus', 'code' => '+375'), +++ 'be' => array('country' => 'Belgium', 'code' => '+32'), +++ 'bz' => array('country' => 'Belize', 'code' => '+501'), +++ 'bj' => array('country' => 'Benin', 'code' => '+229'), +++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), +++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), +++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), +++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), +++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), +++ 'br' => array('country' => 'Brazil', 'code' => '+55'), +++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), +++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), +++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), +++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), +++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), +++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), +++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), +++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), +++ 'ca' => array('country' => 'Canada', 'code' => '+1'), +++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), +++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), +++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), +++ 'td' => array('country' => 'Chad', 'code' => '+235'), +++ 'cl' => array('country' => 'Chile', 'code' => '+56'), +++ 'cn' => array('country' => 'China', 'code' => '+86'), +++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), +++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), +++ 'co' => array('country' => 'Colombia', 'code' => '+57'), +++ 'km' => array('country' => 'Comoros', 'code' => '+269'), +++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), +++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), +++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), +++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), +++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), +++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), +++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), +++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), +++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), +++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), +++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), +++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), +++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), +++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), +++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), +++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), +++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), +++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), +++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), +++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), +++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), +++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), +++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), +++ 'fi' => array('country' => 'Finland', 'code' => '+358'), +++ 'fr' => array('country' => 'France', 'code' => '+33'), +++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), +++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), +++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), +++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), +++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), +++ 'de' => array('country' => 'Germany', 'code' => '+49'), +++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), +++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), +++ 'gr' => array('country' => 'Greece', 'code' => '+30'), +++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), +++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), +++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), +++ 'gu' => array('country' => 'Guam', 'code' => '+1'), +++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), +++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), +++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), +++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), +++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), +++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), +++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), +++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), +++ 'is' => array('country' => 'Iceland', 'code' => '+354'), +++ 'in' => array('country' => 'India', 'code' => '+91'), +++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), +++ 'ir' => array('country' => 'Iran', 'code' => '+98'), +++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), +++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), +++ 'il' => array('country' => 'Israel', 'code' => '+972'), +++ 'it' => array('country' => 'Italy', 'code' => '+39'), +++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), +++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), +++ 'jp' => array('country' => 'Japan', 'code' => '+81'), +++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), +++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), +++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), +++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), +++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), +++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), +++ 'la' => array('country' => 'Laos', 'code' => '+856'), +++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), +++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), +++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), +++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), +++ 'ly' => array('country' => 'Libya', 'code' => '+218'), +++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), +++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), +++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), +++ 'mo' => array('country' => 'Macau', 'code' => '+853'), +++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), +++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), +++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), +++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), +++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), +++ 'ml' => array('country' => 'Mali', 'code' => '+223'), +++ 'mt' => array('country' => 'Malta', 'code' => '+356'), +++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), +++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), +++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), +++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), +++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), +++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), +++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), +++ 'md' => array('country' => 'Moldova', 'code' => '+373'), +++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), +++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), +++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), +++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), +++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), +++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), +++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), +++ 'na' => array('country' => 'Namibia', 'code' => '+264'), +++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), +++ 'np' => array('country' => 'Nepal', 'code' => '+977'), +++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), +++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), +++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), +++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), +++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), +++ 'ne' => array('country' => 'Niger', 'code' => '+227'), +++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), +++ 'nu' => array('country' => 'Niue', 'code' => '+683'), +++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), +++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), +++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), +++ 'no' => array('country' => 'Norway', 'code' => '+47'), +++ 'om' => array('country' => 'Oman', 'code' => '+968'), +++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), +++ 'pw' => array('country' => 'Palau', 'code' => '+680'), +++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), +++ 'pa' => array('country' => 'Panama', 'code' => '+507'), +++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), +++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), +++ 'pe' => array('country' => 'Peru', 'code' => '+51'), +++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), +++ 'pl' => array('country' => 'Poland', 'code' => '+48'), +++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), +++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), +++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), +++ 'ro' => array('country' => 'Romania', 'code' => '+40'), +++ 'ru' => array('country' => 'Russia', 'code' => '+7'), +++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), +++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), +++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), +++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), +++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), +++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), +++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), +++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), +++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), +++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), +++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), +++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), +++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), +++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), +++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), +++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), +++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), +++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), +++ 'so' => array('country' => 'Somalia', 'code' => '+252'), +++ 'za' => array('country' => 'South Africa', 'code' => '+27'), +++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), +++ 'es' => array('country' => 'Spain', 'code' => '+34'), +++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), +++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), +++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), +++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), +++ 'se' => array('country' => 'Sweden', 'code' => '+46'), +++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), +++ 'sy' => array('country' => 'Syria', 'code' => '+963'), +++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), +++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), +++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), +++ 'th' => array('country' => 'Thailand', 'code' => '+66'), +++ 'tg' => array('country' => 'Togo', 'code' => '+228'), +++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), +++ 'to' => array('country' => 'Tonga', 'code' => '+676'), +++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), +++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), +++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), +++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), +++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), +++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), +++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), +++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), +++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), +++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), +++ 'us' => array('country' => 'United States', 'code' => '+1'), +++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), +++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), +++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), +++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), +++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), +++ 've' => array('country' => 'Venezuela', 'code' => '+58'), +++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), +++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), +++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), +++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), +++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), +++ ); +++ +++ if (is_null($cc)) { +++ return $country_code; +++ } +++ elseif (isset($country_code[$cc])) { +++ return $country_code[$cc]; +++ } +++ +++ return FALSE; +++} ++ ++--- includes/phone.ph.inc +++++ includes/phone.ph.inc ++@@ -0,0 +1,108 @@ +++ 12)) { +++ $error = t('%phone_input is not a valid phone number, it should have at least 8 digits number like "2 999 9999" and maximum of 12 digits like "12345 999 9999".', array('%phone_input' => $number)); +++ return FALSE; +++ } +++ return TRUE; +++} +++ +++/** +++ * Cleanup user-entered values for a phone number field for storing to DB. +++ * +++ * @param $number +++ * A single phone number item. +++ */ +++function ph_sanitize_number(&$number) { +++ $number = preg_replace('/^([0]*)/', '', $number); +++} +++ +++/** +++ * Default formatter for international phone number. +++ * +++ * @param $number +++ * Phone number. +++ */ +++function ph_formatter_default($number) { +++ $regex = "/ +++ # 5 digit area code. +++ ( +++ (\d{5}) # capture 5 digit area code +++ (\d{3}) # capture first set of numbers in the local number +++ (\d{4}) # capture second set of numbers in the local number +++ | +++ # 4 digit area code. +++ (\d{4}) # capture 4 digit area code +++ (\d{3}) # capture first set of numbers in the local number +++ (\d{4}) # capture second set of numbers in the local number +++ | +++ # 3 digit area code. +++ (\d{3}) # capture 3 digit area code +++ (\d{3}) # capture first set of numbers in the local number +++ (\d{4}) # capture second set of numbers in the local number +++ | +++ # 2 digit area code. +++ (\d{2}) # capture 2 digit area code +++ (\d{3}) # capture first set of numbers in the local number +++ (\d{4}) # capture second set of numbers in the local number +++ | +++ # 1 digit area code. +++ (\d{1}) # capture 1 digit area code +++ (\d{3}) # capture first set of numbers in the local number +++ (\d{4}) # capture second set of numbers in the local number +++ ) +++ /x"; +++ +++ preg_match($regex, $number, $matches); +++ if (isset($matches[14]) && !empty($matches[14])) { +++ $area = $matches[14]; +++ $head_num = $matches[15]; +++ $tail_num = $matches[16]; +++ } +++ elseif (isset($matches[11]) && !empty($matches[11])) { +++ $area = $matches[11]; +++ $head_num = $matches[12]; +++ $tail_num = $matches[13]; +++ } +++ elseif (isset($matches[8]) && !empty($matches[8])) { +++ $area = $matches[8]; +++ $head_num = $matches[9]; +++ $tail_num = $matches[10]; +++ } +++ elseif (isset($matches[5]) && !empty($matches[5])) { +++ $area = $matches[5]; +++ $head_num = $matches[6]; +++ $tail_num = $matches[7]; +++ } +++ else { +++ $area = $matches[2]; +++ $head_num = $matches[3]; +++ $tail_num = $matches[4]; +++ } +++ return '(' . $area . ') ' . $head_num . '-' . $tail_num; +++} ++ ++--- js/cck_phone.manage_field.js +++++ js/cck_phone.manage_field.js ++@@ -0,0 +1,113 @@ +++// $Id: cck_phone.js,v 1.2 2010/07/12 09:54:52 ckng Exp $ +++ +++Drupal.PhoneNumber = Drupal.PhoneNumber || {}; +++ +++/** +++ * Filters checkboxes based on their label. +++ * This code is shamelessly taken from checkbox_filter +++ */ +++Drupal.PhoneNumber.filter = function() { +++ var field = $(this); +++ var checkboxes = $('.form-checkboxes .form-item', field.parent().parent()); +++ var found = false; +++ var label = ""; +++ var option = null; +++ for (var i = 0; i < checkboxes.length; i++) { +++ option = checkboxes.eq(i); +++ label = Drupal.PhoneNumber.trim(option.text()); +++ if (label.toUpperCase().indexOf(field.val().toUpperCase()) < 0) { +++ option.hide(); +++ } else { +++ option.show(); +++ } +++ } +++} +++ +++/** +++ * Trims whitespace from strings +++ */ +++Drupal.PhoneNumber.trim = function(str) { +++ var str = str.replace(/^\s\s*/, ''), +++ ws = /\s/, +++ i = str.length; +++ while (ws.test(str.charAt(--i))); +++ return str.slice(0, i + 1); +++} +++ +++/** +++ * Check/Uncheck all checkboxes +++ */ +++Drupal.PhoneNumber.checkall = function(e) { +++ var field = $(this); +++ var checkboxes = $('.form-checkboxes .form-item:visible .form-checkbox', field.parent().parent()); +++ +++ var checked = (field.text() == Drupal.t('Select all')); +++ if (checked) { +++ checkboxes.attr('checked', true); +++ field.text(Drupal.t('Deselect all')); +++ } +++ else { +++ checkboxes.attr('checked', false); +++ Drupal.PhoneNumber.checkDefault(); +++ field.text(Drupal.t('Select all')); +++ } +++} +++ +++/** +++ * Country selection should include default country code by default. +++ */ +++Drupal.PhoneNumber.checkDefault = function(e) { +++ var defaultCC = $('#edit-default-country').val(); +++ var span = $('').append(Drupal.t('Default')); +++ +++ if ($('.cck-phone-default-country').find('.form-checkbox').val() == defaultCC) { +++ $('#edit-country-selection-' + defaultCC) +++ .attr('checked', 'checked'); +++ } +++ else { +++ $('.cck-phone-default-country') +++ .removeClass('cck-phone-default-country') +++ .find('span.default-cc').remove(); +++ +++ +++ $('#edit-country-selection-' + defaultCC) +++ .attr('checked', 'checked') +++ .parents('.form-item:first') +++ .addClass('cck-phone-default-country') +++ .append(span); +++ } +++} +++ +++/** +++ * Attach a filtering textfield to checkboxes. +++ */ +++Drupal.behaviors.PhoneNumber = function (context) { +++ // Toggle collapsible on selection +++ $('#edit-all-country-codes').change(function() { +++ if ($(this).attr('checked')) { +++ $('fieldset.cck-phone-settings').addClass('collapsed'); +++ } +++ else { +++ $('fieldset.cck-phone-settings').removeClass('collapsed'); +++ } +++ }); +++ $('#edit-all-country-codes').trigger('change'); +++ +++ // Ensure the new default country is checked +++ $('#edit-default-country, .cck-phone-settings .form-checkboxes').bind('change', Drupal.PhoneNumber.checkDefault); +++ $('#edit-default-country').trigger('change'); +++ $('form#content-field-edit-form').submit(Drupal.PhoneNumber.checkDefault); +++ +++ +++ // Filter for countries +++ var form = '
' +++ + ' ' +++ + ' ' +++ + '
' +++ + ''; +++ $('.cck-phone-settings .form-checkboxes', context).before(form); +++ $('input.cck-phone-filter').bind('keyup', Drupal.PhoneNumber.filter); +++ $('a.cck-phone-check').bind('click', Drupal.PhoneNumber.checkall); +++} ++ ++--- theme/phone-field-view.tpl.php +++++ theme/phone-field-view.tpl.php ++@@ -0,0 +1,20 @@ +++ +++ +++ +++ +++ +++ ++ ++ + +--- cck_phone_countrycodes.inc.tortoise.removed ++++ cck_phone_countrycodes.inc.tortoise.removed +@@ -0,0 +1,266 @@ ++ array('country' => 'Afghanistan', 'code' => '+93'), ++ 'al' => array('country' => 'Albania', 'code' => '+355'), ++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), ++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), ++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), ++ 'ao' => array('country' => 'Angola', 'code' => '+244'), ++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), ++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), ++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), ++ 'am' => array('country' => 'Armenia', 'code' => '+374'), ++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), ++ 'au' => array('country' => 'Australia', 'code' => '+61'), ++ 'at' => array('country' => 'Austria', 'code' => '+43'), ++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), ++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), ++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), ++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), ++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), ++ 'by' => array('country' => 'Belarus', 'code' => '+375'), ++ 'be' => array('country' => 'Belgium', 'code' => '+32'), ++ 'bz' => array('country' => 'Belize', 'code' => '+501'), ++ 'bj' => array('country' => 'Benin', 'code' => '+229'), ++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), ++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), ++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), ++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), ++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), ++ 'br' => array('country' => 'Brazil', 'code' => '+55'), ++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), ++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), ++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), ++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), ++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), ++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), ++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), ++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), ++ 'ca' => array('country' => 'Canada', 'code' => '+1'), ++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), ++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), ++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), ++ 'td' => array('country' => 'Chad', 'code' => '+235'), ++ 'cl' => array('country' => 'Chile', 'code' => '+56'), ++ 'cn' => array('country' => 'China', 'code' => '+86'), ++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), ++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), ++ 'co' => array('country' => 'Colombia', 'code' => '+57'), ++ 'km' => array('country' => 'Comoros', 'code' => '+269'), ++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), ++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), ++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), ++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), ++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), ++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), ++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), ++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), ++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), ++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), ++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), ++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), ++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), ++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), ++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), ++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), ++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), ++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), ++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), ++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), ++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), ++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), ++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), ++ 'fi' => array('country' => 'Finland', 'code' => '+358'), ++ 'fr' => array('country' => 'France', 'code' => '+33'), ++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), ++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), ++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), ++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), ++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), ++ 'de' => array('country' => 'Germany', 'code' => '+49'), ++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), ++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), ++ 'gr' => array('country' => 'Greece', 'code' => '+30'), ++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), ++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), ++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), ++ 'gu' => array('country' => 'Guam', 'code' => '+1'), ++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), ++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), ++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), ++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), ++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), ++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), ++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), ++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), ++ 'is' => array('country' => 'Iceland', 'code' => '+354'), ++ 'in' => array('country' => 'India', 'code' => '+91'), ++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), ++ 'ir' => array('country' => 'Iran', 'code' => '+98'), ++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), ++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), ++ 'il' => array('country' => 'Israel', 'code' => '+972'), ++ 'it' => array('country' => 'Italy', 'code' => '+39'), ++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), ++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), ++ 'jp' => array('country' => 'Japan', 'code' => '+81'), ++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), ++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), ++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), ++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), ++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), ++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), ++ 'la' => array('country' => 'Laos', 'code' => '+856'), ++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), ++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), ++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), ++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), ++ 'ly' => array('country' => 'Libya', 'code' => '+218'), ++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), ++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), ++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), ++ 'mo' => array('country' => 'Macau', 'code' => '+853'), ++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), ++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), ++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), ++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), ++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), ++ 'ml' => array('country' => 'Mali', 'code' => '+223'), ++ 'mt' => array('country' => 'Malta', 'code' => '+356'), ++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), ++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), ++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), ++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), ++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), ++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), ++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), ++ 'md' => array('country' => 'Moldova', 'code' => '+373'), ++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), ++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), ++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), ++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), ++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), ++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), ++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), ++ 'na' => array('country' => 'Namibia', 'code' => '+264'), ++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), ++ 'np' => array('country' => 'Nepal', 'code' => '+977'), ++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), ++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), ++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), ++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), ++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), ++ 'ne' => array('country' => 'Niger', 'code' => '+227'), ++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), ++ 'nu' => array('country' => 'Niue', 'code' => '+683'), ++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), ++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), ++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), ++ 'no' => array('country' => 'Norway', 'code' => '+47'), ++ 'om' => array('country' => 'Oman', 'code' => '+968'), ++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), ++ 'pw' => array('country' => 'Palau', 'code' => '+680'), ++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), ++ 'pa' => array('country' => 'Panama', 'code' => '+507'), ++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), ++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), ++ 'pe' => array('country' => 'Peru', 'code' => '+51'), ++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), ++ 'pl' => array('country' => 'Poland', 'code' => '+48'), ++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), ++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), ++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), ++ 'ro' => array('country' => 'Romania', 'code' => '+40'), ++ 'ru' => array('country' => 'Russia', 'code' => '+7'), ++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), ++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), ++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), ++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), ++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), ++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), ++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), ++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), ++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), ++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), ++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), ++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), ++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), ++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), ++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), ++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), ++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), ++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), ++ 'so' => array('country' => 'Somalia', 'code' => '+252'), ++ 'za' => array('country' => 'South Africa', 'code' => '+27'), ++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), ++ 'es' => array('country' => 'Spain', 'code' => '+34'), ++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), ++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), ++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), ++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), ++ 'se' => array('country' => 'Sweden', 'code' => '+46'), ++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), ++ 'sy' => array('country' => 'Syria', 'code' => '+963'), ++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), ++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), ++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), ++ 'th' => array('country' => 'Thailand', 'code' => '+66'), ++ 'tg' => array('country' => 'Togo', 'code' => '+228'), ++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), ++ 'to' => array('country' => 'Tonga', 'code' => '+676'), ++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), ++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), ++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), ++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), ++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), ++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), ++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), ++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), ++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), ++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), ++ 'us' => array('country' => 'United States', 'code' => '+1'), ++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), ++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), ++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), ++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), ++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), ++ 've' => array('country' => 'Venezuela', 'code' => '+58'), ++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), ++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), ++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), ++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), ++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), ++ ); ++ ++ if (is_null($cc)) { ++ return $country_code; ++ } ++ elseif (isset($country_code[$cc])) { ++ return $country_code[$cc]; ++ } ++ ++ return FALSE; ++} + +--- css/cck_phone.css ++++ css/cck_phone.css +@@ -0,0 +1,35 @@ ++/* $Id: cck_phone.css,v 1.2 2010/07/12 09:54:52 ckng Exp $ */ ++.cck-phone-field .form-item { ++ margin: 0; ++} ++ ++.cck-phone-column { ++ float: left; ++} ++.cck-phone-field-phone { ++ width: 15em; ++} ++.cck-phone-field-cc { ++ width: 25em; ++} ++ ++.cck-phone-field-ext { ++ width: 9em; ++} ++.cck-phone-extension { ++ float: left; ++ margin: 0 .5em; ++} ++.cck-phone-field-ext .form-item { ++ float: left; ++} ++ ++.cck-phone-settings .form-checkboxes .form-item { ++ float: left; ++ width: 33%; ++} ++ ++.cck-phone-settings .cck-phone-default-country { ++ background: #eee; ++ font-weight: bold; ++} + +--- includes/cc.template.php ++++ includes/cc.template.php +@@ -0,0 +1,70 @@ ++ $subaddress)); ++ return FALSE; ++ } ++ // Assign $number_error as FALSE if $number is not valid ++ if (!empty($number) && $number_error) { ++ $error = t('%phone_input is not a valid phone number, it should be 10 digits number like "999 999 9999"', array('%phone_input' => $number)); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++ ++/** ++ * Cleanup user-entered values for a phone number field for storing to DB. ++ * ++ * @param $number ++ * A single phone number item. ++ */ ++function CC_sanitize_number(&$number) { ++ // your cleanup like removing trunk prefix ++ $number = preg_replace('/^([0]*)/', '', $number); ++} ++ ++ ++/** ++ * Default formatter for international phone number. ++ * ++ * @param $number ++ * Phone number. ++ */ ++function CC_formatter_default($number) { ++ // Format the phone number and its area code into human readable format ++ $phone = $number; ++ ++ return $phone; ++} + +--- includes/cck_phone_countrycodes.inc ++++ includes/cck_phone_countrycodes.inc +@@ -0,0 +1,266 @@ ++ array('country' => 'Afghanistan', 'code' => '+93'), ++ 'al' => array('country' => 'Albania', 'code' => '+355'), ++ 'dz' => array('country' => 'Algeria', 'code' => '+213'), ++ 'as' => array('country' => 'American Samoa', 'code' => '+1'), ++ 'ad' => array('country' => 'Andorra', 'code' => '+376'), ++ 'ao' => array('country' => 'Angola', 'code' => '+244'), ++ 'ai' => array('country' => 'Anguilla', 'code' => '+1'), ++ 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), ++ 'ar' => array('country' => 'Argentina', 'code' => '+54'), ++ 'am' => array('country' => 'Armenia', 'code' => '+374'), ++ 'aw' => array('country' => 'Aruba', 'code' => '+297'), ++ 'au' => array('country' => 'Australia', 'code' => '+61'), ++ 'at' => array('country' => 'Austria', 'code' => '+43'), ++ 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), ++ 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), ++ 'bh' => array('country' => 'Bahrain', 'code' => '+973'), ++ 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), ++ 'bb' => array('country' => 'Barbados', 'code' => '+1'), ++ 'by' => array('country' => 'Belarus', 'code' => '+375'), ++ 'be' => array('country' => 'Belgium', 'code' => '+32'), ++ 'bz' => array('country' => 'Belize', 'code' => '+501'), ++ 'bj' => array('country' => 'Benin', 'code' => '+229'), ++ 'bm' => array('country' => 'Bermuda', 'code' => '+1'), ++ 'bt' => array('country' => 'Bhutan', 'code' => '+975'), ++ 'bo' => array('country' => 'Bolivia', 'code' => '+591'), ++ 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), ++ 'bw' => array('country' => 'Botswana', 'code' => '+267'), ++ 'br' => array('country' => 'Brazil', 'code' => '+55'), ++ 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), ++ 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), ++ 'bn' => array('country' => 'Brunei', 'code' => '+673'), ++ 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), ++ 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), ++ 'bi' => array('country' => 'Burundi', 'code' => '+257'), ++ 'kh' => array('country' => 'Cambodia', 'code' => '+855'), ++ 'cm' => array('country' => 'Cameroon', 'code' => '+237'), ++ 'ca' => array('country' => 'Canada', 'code' => '+1'), ++ 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), ++ 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), ++ 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), ++ 'td' => array('country' => 'Chad', 'code' => '+235'), ++ 'cl' => array('country' => 'Chile', 'code' => '+56'), ++ 'cn' => array('country' => 'China', 'code' => '+86'), ++ 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), ++ 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), ++ 'co' => array('country' => 'Colombia', 'code' => '+57'), ++ 'km' => array('country' => 'Comoros', 'code' => '+269'), ++ 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), ++ 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), ++ 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), ++ 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), ++ 'hr' => array('country' => 'Croatia', 'code' => '+385'), ++ 'cu' => array('country' => 'Cuba', 'code' => '+53'), ++ 'cy' => array('country' => 'Cyprus', 'code' => '+357'), ++ 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), ++ 'dk' => array('country' => 'Denmark', 'code' => '+45'), ++ 'dj' => array('country' => 'Djibouti', 'code' => '+253'), ++ 'dm' => array('country' => 'Dominica', 'code' => '+1'), ++ 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), ++ 'tp' => array('country' => 'East Timor', 'code' => '+670'), ++ 'ec' => array('country' => 'Ecuador', 'code' => '+593'), ++ 'eg' => array('country' => 'Egypt', 'code' => '+20'), ++ 'sv' => array('country' => 'El Salvador', 'code' => '+503'), ++ 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), ++ 'er' => array('country' => 'Eritrea', 'code' => '+291'), ++ 'ee' => array('country' => 'Estonia', 'code' => '+372'), ++ 'et' => array('country' => 'Ethiopia', 'code' => '+251'), ++ 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), ++ 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), ++ 'fj' => array('country' => 'Fiji', 'code' => '+679'), ++ 'fi' => array('country' => 'Finland', 'code' => '+358'), ++ 'fr' => array('country' => 'France', 'code' => '+33'), ++ 'gf' => array('country' => 'French Guiana', 'code' => '+594'), ++ 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), ++ 'ga' => array('country' => 'Gabon', 'code' => '+241'), ++ 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), ++ 'ge' => array('country' => 'Georgia', 'code' => '+995'), ++ 'de' => array('country' => 'Germany', 'code' => '+49'), ++ 'gh' => array('country' => 'Ghana', 'code' => '+233'), ++ 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), ++ 'gr' => array('country' => 'Greece', 'code' => '+30'), ++ 'gl' => array('country' => 'Greenland', 'code' => '+299'), ++ 'gd' => array('country' => 'Grenada', 'code' => '+1'), ++ 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), ++ 'gu' => array('country' => 'Guam', 'code' => '+1'), ++ 'gt' => array('country' => 'Guatemala', 'code' => '+502'), ++ 'gn' => array('country' => 'Guinea', 'code' => '+224'), ++ 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), ++ 'gy' => array('country' => 'Guyana', 'code' => '+592'), ++ 'ht' => array('country' => 'Haiti', 'code' => '+509'), ++ 'hn' => array('country' => 'Honduras', 'code' => '+504'), ++ 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), ++ 'hu' => array('country' => 'Hungary', 'code' => '+36'), ++ 'is' => array('country' => 'Iceland', 'code' => '+354'), ++ 'in' => array('country' => 'India', 'code' => '+91'), ++ 'id' => array('country' => 'Indonesia', 'code' => '+62'), ++ 'ir' => array('country' => 'Iran', 'code' => '+98'), ++ 'iq' => array('country' => 'Iraq', 'code' => '+964'), ++ 'ie' => array('country' => 'Ireland', 'code' => '+353'), ++ 'il' => array('country' => 'Israel', 'code' => '+972'), ++ 'it' => array('country' => 'Italy', 'code' => '+39'), ++ 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), ++ 'jm' => array('country' => 'Jamaica', 'code' => '+1'), ++ 'jp' => array('country' => 'Japan', 'code' => '+81'), ++ 'jo' => array('country' => 'Jordan', 'code' => '+962'), ++ 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), ++ 'ke' => array('country' => 'Kenya', 'code' => '+254'), ++ 'ki' => array('country' => 'Kiribati', 'code' => '+686'), ++ 'kw' => array('country' => 'Kuwait', 'code' => '+965'), ++ 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), ++ 'la' => array('country' => 'Laos', 'code' => '+856'), ++ 'lv' => array('country' => 'Latvia', 'code' => '+371'), ++ 'lb' => array('country' => 'Lebanon', 'code' => '+961'), ++ 'ls' => array('country' => 'Lesotho', 'code' => '+266'), ++ 'lr' => array('country' => 'Liberia', 'code' => '+231'), ++ 'ly' => array('country' => 'Libya', 'code' => '+218'), ++ 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), ++ 'lt' => array('country' => 'Lithuania', 'code' => '+370'), ++ 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), ++ 'mo' => array('country' => 'Macau', 'code' => '+853'), ++ 'mk' => array('country' => 'Macedonia', 'code' => '+389'), ++ 'mg' => array('country' => 'Madagascar', 'code' => '+261'), ++ 'mw' => array('country' => 'Malawi', 'code' => '+265'), ++ 'my' => array('country' => 'Malaysia', 'code' => '+60'), ++ 'mv' => array('country' => 'Maldives', 'code' => '+960'), ++ 'ml' => array('country' => 'Mali', 'code' => '+223'), ++ 'mt' => array('country' => 'Malta', 'code' => '+356'), ++ 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), ++ 'mq' => array('country' => 'Martinique', 'code' => '+596'), ++ 'mr' => array('country' => 'Mauritania', 'code' => '+222'), ++ 'mu' => array('country' => 'Mauritius', 'code' => '+230'), ++ 'yt' => array('country' => 'Mayotte', 'code' => '+269'), ++ 'mx' => array('country' => 'Mexico', 'code' => '+52'), ++ 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), ++ 'md' => array('country' => 'Moldova', 'code' => '+373'), ++ 'mc' => array('country' => 'Monaco', 'code' => '+377'), ++ 'mn' => array('country' => 'Mongolia', 'code' => '+976'), ++ 'me' => array('country' => 'Montenegro', 'code' => '+382'), ++ 'ms' => array('country' => 'Montserrat', 'code' => '+1'), ++ 'ma' => array('country' => 'Morocco', 'code' => '+212'), ++ 'mz' => array('country' => 'Mozambique', 'code' => '+258'), ++ 'mm' => array('country' => 'Myanmar', 'code' => '+95'), ++ 'na' => array('country' => 'Namibia', 'code' => '+264'), ++ 'nr' => array('country' => 'Nauru', 'code' => '+674'), ++ 'np' => array('country' => 'Nepal', 'code' => '+977'), ++ 'nl' => array('country' => 'Netherlands', 'code' => '+31'), ++ 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), ++ 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), ++ 'nz' => array('country' => 'New Zealand', 'code' => '+64'), ++ 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), ++ 'ne' => array('country' => 'Niger', 'code' => '+227'), ++ 'ng' => array('country' => 'Nigeria', 'code' => '+234'), ++ 'nu' => array('country' => 'Niue', 'code' => '+683'), ++ 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), ++ 'kp' => array('country' => 'North Korea', 'code' => '+850'), ++ 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), ++ 'no' => array('country' => 'Norway', 'code' => '+47'), ++ 'om' => array('country' => 'Oman', 'code' => '+968'), ++ 'pk' => array('country' => 'Pakistan', 'code' => '+92'), ++ 'pw' => array('country' => 'Palau', 'code' => '+680'), ++ 'ps' => array('country' => 'Palestine', 'code' => '+970'), ++ 'pa' => array('country' => 'Panama', 'code' => '+507'), ++ 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), ++ 'py' => array('country' => 'Paraguay', 'code' => '+595'), ++ 'pe' => array('country' => 'Peru', 'code' => '+51'), ++ 'ph' => array('country' => 'Philippines', 'code' => '+63'), ++ 'pl' => array('country' => 'Poland', 'code' => '+48'), ++ 'pt' => array('country' => 'Portugal', 'code' => '+351'), ++ 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), ++ 'qa' => array('country' => 'Qatar', 'code' => '+974'), ++ 'ro' => array('country' => 'Romania', 'code' => '+40'), ++ 'ru' => array('country' => 'Russia', 'code' => '+7'), ++ 'rw' => array('country' => 'Rwanda', 'code' => '+250'), ++ 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), ++ 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), ++ 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), ++ 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), ++ 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), ++ 'ws' => array('country' => 'Samoa', 'code' => '+1'), ++ 'sm' => array('country' => 'San Marino', 'code' => '+378'), ++ 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), ++ 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), ++ 'sn' => array('country' => 'Senegal', 'code' => '+221'), ++ 'rs' => array('country' => 'Serbia', 'code' => '+381'), ++ 'sc' => array('country' => 'Seychelles', 'code' => '+248'), ++ 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), ++ 'sg' => array('country' => 'Singapore', 'code' => '+65'), ++ 'sk' => array('country' => 'Slovakia', 'code' => '+421'), ++ 'si' => array('country' => 'Slovenia', 'code' => '+386'), ++ 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), ++ 'so' => array('country' => 'Somalia', 'code' => '+252'), ++ 'za' => array('country' => 'South Africa', 'code' => '+27'), ++ 'kr' => array('country' => 'South Korea', 'code' => '+82'), ++ 'es' => array('country' => 'Spain', 'code' => '+34'), ++ 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), ++ 'sd' => array('country' => 'Sudan', 'code' => '+249'), ++ 'sr' => array('country' => 'Suriname', 'code' => '+597'), ++ 'sz' => array('country' => 'Swaziland', 'code' => '+268'), ++ 'se' => array('country' => 'Sweden', 'code' => '+46'), ++ 'ch' => array('country' => 'Switzerland', 'code' => '+41'), ++ 'sy' => array('country' => 'Syria', 'code' => '+963'), ++ 'tw' => array('country' => 'Taiwan', 'code' => '+886'), ++ 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), ++ 'tz' => array('country' => 'Tanzania', 'code' => '+255'), ++ 'th' => array('country' => 'Thailand', 'code' => '+66'), ++ 'tg' => array('country' => 'Togo', 'code' => '+228'), ++ 'tk' => array('country' => 'Tokelau', 'code' => '+690'), ++ 'to' => array('country' => 'Tonga', 'code' => '+676'), ++ 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), ++ 'tn' => array('country' => 'Tunisia', 'code' => '+216'), ++ 'tr' => array('country' => 'Turkey', 'code' => '+90'), ++ 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), ++ 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), ++ 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), ++ 'ug' => array('country' => 'Uganda', 'code' => '+256'), ++ 'ua' => array('country' => 'Ukraine', 'code' => '+380'), ++ 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), ++ 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), ++ 'us' => array('country' => 'United States', 'code' => '+1'), ++ 'uy' => array('country' => 'Uruguay', 'code' => '+598'), ++ 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), ++ 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), ++ 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), ++ 'va' => array('country' => 'Vatican City', 'code' => '+39'), ++ 've' => array('country' => 'Venezuela', 'code' => '+58'), ++ 'vn' => array('country' => 'Vietnam', 'code' => '+84'), ++ 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), ++ 'ye' => array('country' => 'Yemen', 'code' => '+967'), ++ 'zm' => array('country' => 'Zambia', 'code' => '+260'), ++ 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), ++ ); ++ ++ if (is_null($cc)) { ++ return $country_code; ++ } ++ elseif (isset($country_code[$cc])) { ++ return $country_code[$cc]; ++ } ++ ++ return FALSE; ++} + +--- includes/phone.ph.inc ++++ includes/phone.ph.inc +@@ -0,0 +1,108 @@ ++ 12)) { ++ $error = t('%phone_input is not a valid phone number, it should have at least 8 digits number like "2 999 9999" and maximum of 12 digits like "12345 999 9999".', array('%phone_input' => $number)); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/** ++ * Cleanup user-entered values for a phone number field for storing to DB. ++ * ++ * @param $number ++ * A single phone number item. ++ */ ++function ph_sanitize_number(&$number) { ++ $number = preg_replace('/^([0]*)/', '', $number); ++} ++ ++/** ++ * Default formatter for international phone number. ++ * ++ * @param $number ++ * Phone number. ++ */ ++function ph_formatter_default($number) { ++ $regex = "/ ++ # 5 digit area code. ++ ( ++ (\d{5}) # capture 5 digit area code ++ (\d{3}) # capture first set of numbers in the local number ++ (\d{4}) # capture second set of numbers in the local number ++ | ++ # 4 digit area code. ++ (\d{4}) # capture 4 digit area code ++ (\d{3}) # capture first set of numbers in the local number ++ (\d{4}) # capture second set of numbers in the local number ++ | ++ # 3 digit area code. ++ (\d{3}) # capture 3 digit area code ++ (\d{3}) # capture first set of numbers in the local number ++ (\d{4}) # capture second set of numbers in the local number ++ | ++ # 2 digit area code. ++ (\d{2}) # capture 2 digit area code ++ (\d{3}) # capture first set of numbers in the local number ++ (\d{4}) # capture second set of numbers in the local number ++ | ++ # 1 digit area code. ++ (\d{1}) # capture 1 digit area code ++ (\d{3}) # capture first set of numbers in the local number ++ (\d{4}) # capture second set of numbers in the local number ++ ) ++ /x"; ++ ++ preg_match($regex, $number, $matches); ++ if (isset($matches[14]) && !empty($matches[14])) { ++ $area = $matches[14]; ++ $head_num = $matches[15]; ++ $tail_num = $matches[16]; ++ } ++ elseif (isset($matches[11]) && !empty($matches[11])) { ++ $area = $matches[11]; ++ $head_num = $matches[12]; ++ $tail_num = $matches[13]; ++ } ++ elseif (isset($matches[8]) && !empty($matches[8])) { ++ $area = $matches[8]; ++ $head_num = $matches[9]; ++ $tail_num = $matches[10]; ++ } ++ elseif (isset($matches[5]) && !empty($matches[5])) { ++ $area = $matches[5]; ++ $head_num = $matches[6]; ++ $tail_num = $matches[7]; ++ } ++ else { ++ $area = $matches[2]; ++ $head_num = $matches[3]; ++ $tail_num = $matches[4]; ++ } ++ return '(' . $area . ') ' . $head_num . '-' . $tail_num; ++} + +--- js/cck_phone.manage_field.js ++++ js/cck_phone.manage_field.js +@@ -0,0 +1,113 @@ ++// $Id: cck_phone.js,v 1.2 2010/07/12 09:54:52 ckng Exp $ ++ ++Drupal.PhoneNumber = Drupal.PhoneNumber || {}; ++ ++/** ++ * Filters checkboxes based on their label. ++ * This code is shamelessly taken from checkbox_filter ++ */ ++Drupal.PhoneNumber.filter = function() { ++ var field = $(this); ++ var checkboxes = $('.form-checkboxes .form-item', field.parent().parent()); ++ var found = false; ++ var label = ""; ++ var option = null; ++ for (var i = 0; i < checkboxes.length; i++) { ++ option = checkboxes.eq(i); ++ label = Drupal.PhoneNumber.trim(option.text()); ++ if (label.toUpperCase().indexOf(field.val().toUpperCase()) < 0) { ++ option.hide(); ++ } else { ++ option.show(); ++ } ++ } ++} ++ ++/** ++ * Trims whitespace from strings ++ */ ++Drupal.PhoneNumber.trim = function(str) { ++ var str = str.replace(/^\s\s*/, ''), ++ ws = /\s/, ++ i = str.length; ++ while (ws.test(str.charAt(--i))); ++ return str.slice(0, i + 1); ++} ++ ++/** ++ * Check/Uncheck all checkboxes ++ */ ++Drupal.PhoneNumber.checkall = function(e) { ++ var field = $(this); ++ var checkboxes = $('.form-checkboxes .form-item:visible .form-checkbox', field.parent().parent()); ++ ++ var checked = (field.text() == Drupal.t('Select all')); ++ if (checked) { ++ checkboxes.attr('checked', true); ++ field.text(Drupal.t('Deselect all')); ++ } ++ else { ++ checkboxes.attr('checked', false); ++ Drupal.PhoneNumber.checkDefault(); ++ field.text(Drupal.t('Select all')); ++ } ++} ++ ++/** ++ * Country selection should include default country code by default. ++ */ ++Drupal.PhoneNumber.checkDefault = function(e) { ++ var defaultCC = $('#edit-default-country').val(); ++ var span = $('').append(Drupal.t('Default')); ++ ++ if ($('.cck-phone-default-country').find('.form-checkbox').val() == defaultCC) { ++ $('#edit-country-selection-' + defaultCC) ++ .attr('checked', 'checked'); ++ } ++ else { ++ $('.cck-phone-default-country') ++ .removeClass('cck-phone-default-country') ++ .find('span.default-cc').remove(); ++ ++ ++ $('#edit-country-selection-' + defaultCC) ++ .attr('checked', 'checked') ++ .parents('.form-item:first') ++ .addClass('cck-phone-default-country') ++ .append(span); ++ } ++} ++ ++/** ++ * Attach a filtering textfield to checkboxes. ++ */ ++Drupal.behaviors.PhoneNumber = function (context) { ++ // Toggle collapsible on selection ++ $('#edit-all-country-codes').change(function() { ++ if ($(this).attr('checked')) { ++ $('fieldset.cck-phone-settings').addClass('collapsed'); ++ } ++ else { ++ $('fieldset.cck-phone-settings').removeClass('collapsed'); ++ } ++ }); ++ $('#edit-all-country-codes').trigger('change'); ++ ++ // Ensure the new default country is checked ++ $('#edit-default-country, .cck-phone-settings .form-checkboxes').bind('change', Drupal.PhoneNumber.checkDefault); ++ $('#edit-default-country').trigger('change'); ++ $('form#content-field-edit-form').submit(Drupal.PhoneNumber.checkDefault); ++ ++ ++ // Filter for countries ++ var form = '
' ++ + ' ' ++ + ' ' ++ + '
' ++ + ''; ++ $('.cck-phone-settings .form-checkboxes', context).before(form); ++ $('input.cck-phone-filter').bind('keyup', Drupal.PhoneNumber.filter); ++ $('a.cck-phone-check').bind('click', Drupal.PhoneNumber.checkall); ++} + +--- theme/phone-field-view.tpl.php ++++ theme/phone-field-view.tpl.php +@@ -0,0 +1,27 @@ ++ ++ ++ > ++ ++ ++ ++ ++ ++ ++ + + --- cck_phone_countrycodes.inc.tortoise.removed +++ cck_phone_countrycodes.inc.tortoise.removed @@ -0,0 +1,266 @@ + array('country' => 'Afghanistan', 'code' => '+93'), + 'al' => array('country' => 'Albania', 'code' => '+355'), + 'dz' => array('country' => 'Algeria', 'code' => '+213'), + 'as' => array('country' => 'American Samoa', 'code' => '+1'), + 'ad' => array('country' => 'Andorra', 'code' => '+376'), + 'ao' => array('country' => 'Angola', 'code' => '+244'), + 'ai' => array('country' => 'Anguilla', 'code' => '+1'), + 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), + 'ar' => array('country' => 'Argentina', 'code' => '+54'), + 'am' => array('country' => 'Armenia', 'code' => '+374'), + 'aw' => array('country' => 'Aruba', 'code' => '+297'), + 'au' => array('country' => 'Australia', 'code' => '+61'), + 'at' => array('country' => 'Austria', 'code' => '+43'), + 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), + 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), + 'bh' => array('country' => 'Bahrain', 'code' => '+973'), + 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), + 'bb' => array('country' => 'Barbados', 'code' => '+1'), + 'by' => array('country' => 'Belarus', 'code' => '+375'), + 'be' => array('country' => 'Belgium', 'code' => '+32'), + 'bz' => array('country' => 'Belize', 'code' => '+501'), + 'bj' => array('country' => 'Benin', 'code' => '+229'), + 'bm' => array('country' => 'Bermuda', 'code' => '+1'), + 'bt' => array('country' => 'Bhutan', 'code' => '+975'), + 'bo' => array('country' => 'Bolivia', 'code' => '+591'), + 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), + 'bw' => array('country' => 'Botswana', 'code' => '+267'), + 'br' => array('country' => 'Brazil', 'code' => '+55'), + 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), + 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), + 'bn' => array('country' => 'Brunei', 'code' => '+673'), + 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), + 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), + 'bi' => array('country' => 'Burundi', 'code' => '+257'), + 'kh' => array('country' => 'Cambodia', 'code' => '+855'), + 'cm' => array('country' => 'Cameroon', 'code' => '+237'), + 'ca' => array('country' => 'Canada', 'code' => '+1'), + 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), + 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), + 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), + 'td' => array('country' => 'Chad', 'code' => '+235'), + 'cl' => array('country' => 'Chile', 'code' => '+56'), + 'cn' => array('country' => 'China', 'code' => '+86'), + 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), + 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), + 'co' => array('country' => 'Colombia', 'code' => '+57'), + 'km' => array('country' => 'Comoros', 'code' => '+269'), + 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), + 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), + 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), + 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), + 'hr' => array('country' => 'Croatia', 'code' => '+385'), + 'cu' => array('country' => 'Cuba', 'code' => '+53'), + 'cy' => array('country' => 'Cyprus', 'code' => '+357'), + 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), + 'dk' => array('country' => 'Denmark', 'code' => '+45'), + 'dj' => array('country' => 'Djibouti', 'code' => '+253'), + 'dm' => array('country' => 'Dominica', 'code' => '+1'), + 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), + 'tp' => array('country' => 'East Timor', 'code' => '+670'), + 'ec' => array('country' => 'Ecuador', 'code' => '+593'), + 'eg' => array('country' => 'Egypt', 'code' => '+20'), + 'sv' => array('country' => 'El Salvador', 'code' => '+503'), + 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), + 'er' => array('country' => 'Eritrea', 'code' => '+291'), + 'ee' => array('country' => 'Estonia', 'code' => '+372'), + 'et' => array('country' => 'Ethiopia', 'code' => '+251'), + 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), + 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), + 'fj' => array('country' => 'Fiji', 'code' => '+679'), + 'fi' => array('country' => 'Finland', 'code' => '+358'), + 'fr' => array('country' => 'France', 'code' => '+33'), + 'gf' => array('country' => 'French Guiana', 'code' => '+594'), + 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), + 'ga' => array('country' => 'Gabon', 'code' => '+241'), + 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), + 'ge' => array('country' => 'Georgia', 'code' => '+995'), + 'de' => array('country' => 'Germany', 'code' => '+49'), + 'gh' => array('country' => 'Ghana', 'code' => '+233'), + 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), + 'gr' => array('country' => 'Greece', 'code' => '+30'), + 'gl' => array('country' => 'Greenland', 'code' => '+299'), + 'gd' => array('country' => 'Grenada', 'code' => '+1'), + 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), + 'gu' => array('country' => 'Guam', 'code' => '+1'), + 'gt' => array('country' => 'Guatemala', 'code' => '+502'), + 'gn' => array('country' => 'Guinea', 'code' => '+224'), + 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), + 'gy' => array('country' => 'Guyana', 'code' => '+592'), + 'ht' => array('country' => 'Haiti', 'code' => '+509'), + 'hn' => array('country' => 'Honduras', 'code' => '+504'), + 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), + 'hu' => array('country' => 'Hungary', 'code' => '+36'), + 'is' => array('country' => 'Iceland', 'code' => '+354'), + 'in' => array('country' => 'India', 'code' => '+91'), + 'id' => array('country' => 'Indonesia', 'code' => '+62'), + 'ir' => array('country' => 'Iran', 'code' => '+98'), + 'iq' => array('country' => 'Iraq', 'code' => '+964'), + 'ie' => array('country' => 'Ireland', 'code' => '+353'), + 'il' => array('country' => 'Israel', 'code' => '+972'), + 'it' => array('country' => 'Italy', 'code' => '+39'), + 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), + 'jm' => array('country' => 'Jamaica', 'code' => '+1'), + 'jp' => array('country' => 'Japan', 'code' => '+81'), + 'jo' => array('country' => 'Jordan', 'code' => '+962'), + 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), + 'ke' => array('country' => 'Kenya', 'code' => '+254'), + 'ki' => array('country' => 'Kiribati', 'code' => '+686'), + 'kw' => array('country' => 'Kuwait', 'code' => '+965'), + 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), + 'la' => array('country' => 'Laos', 'code' => '+856'), + 'lv' => array('country' => 'Latvia', 'code' => '+371'), + 'lb' => array('country' => 'Lebanon', 'code' => '+961'), + 'ls' => array('country' => 'Lesotho', 'code' => '+266'), + 'lr' => array('country' => 'Liberia', 'code' => '+231'), + 'ly' => array('country' => 'Libya', 'code' => '+218'), + 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), + 'lt' => array('country' => 'Lithuania', 'code' => '+370'), + 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), + 'mo' => array('country' => 'Macau', 'code' => '+853'), + 'mk' => array('country' => 'Macedonia', 'code' => '+389'), + 'mg' => array('country' => 'Madagascar', 'code' => '+261'), + 'mw' => array('country' => 'Malawi', 'code' => '+265'), + 'my' => array('country' => 'Malaysia', 'code' => '+60'), + 'mv' => array('country' => 'Maldives', 'code' => '+960'), + 'ml' => array('country' => 'Mali', 'code' => '+223'), + 'mt' => array('country' => 'Malta', 'code' => '+356'), + 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), + 'mq' => array('country' => 'Martinique', 'code' => '+596'), + 'mr' => array('country' => 'Mauritania', 'code' => '+222'), + 'mu' => array('country' => 'Mauritius', 'code' => '+230'), + 'yt' => array('country' => 'Mayotte', 'code' => '+269'), + 'mx' => array('country' => 'Mexico', 'code' => '+52'), + 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), + 'md' => array('country' => 'Moldova', 'code' => '+373'), + 'mc' => array('country' => 'Monaco', 'code' => '+377'), + 'mn' => array('country' => 'Mongolia', 'code' => '+976'), + 'me' => array('country' => 'Montenegro', 'code' => '+382'), + 'ms' => array('country' => 'Montserrat', 'code' => '+1'), + 'ma' => array('country' => 'Morocco', 'code' => '+212'), + 'mz' => array('country' => 'Mozambique', 'code' => '+258'), + 'mm' => array('country' => 'Myanmar', 'code' => '+95'), + 'na' => array('country' => 'Namibia', 'code' => '+264'), + 'nr' => array('country' => 'Nauru', 'code' => '+674'), + 'np' => array('country' => 'Nepal', 'code' => '+977'), + 'nl' => array('country' => 'Netherlands', 'code' => '+31'), + 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), + 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), + 'nz' => array('country' => 'New Zealand', 'code' => '+64'), + 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), + 'ne' => array('country' => 'Niger', 'code' => '+227'), + 'ng' => array('country' => 'Nigeria', 'code' => '+234'), + 'nu' => array('country' => 'Niue', 'code' => '+683'), + 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), + 'kp' => array('country' => 'North Korea', 'code' => '+850'), + 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), + 'no' => array('country' => 'Norway', 'code' => '+47'), + 'om' => array('country' => 'Oman', 'code' => '+968'), + 'pk' => array('country' => 'Pakistan', 'code' => '+92'), + 'pw' => array('country' => 'Palau', 'code' => '+680'), + 'ps' => array('country' => 'Palestine', 'code' => '+970'), + 'pa' => array('country' => 'Panama', 'code' => '+507'), + 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), + 'py' => array('country' => 'Paraguay', 'code' => '+595'), + 'pe' => array('country' => 'Peru', 'code' => '+51'), + 'ph' => array('country' => 'Philippines', 'code' => '+63'), + 'pl' => array('country' => 'Poland', 'code' => '+48'), + 'pt' => array('country' => 'Portugal', 'code' => '+351'), + 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), + 'qa' => array('country' => 'Qatar', 'code' => '+974'), + 'ro' => array('country' => 'Romania', 'code' => '+40'), + 'ru' => array('country' => 'Russia', 'code' => '+7'), + 'rw' => array('country' => 'Rwanda', 'code' => '+250'), + 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), + 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), + 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), + 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), + 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), + 'ws' => array('country' => 'Samoa', 'code' => '+1'), + 'sm' => array('country' => 'San Marino', 'code' => '+378'), + 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), + 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), + 'sn' => array('country' => 'Senegal', 'code' => '+221'), + 'rs' => array('country' => 'Serbia', 'code' => '+381'), + 'sc' => array('country' => 'Seychelles', 'code' => '+248'), + 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), + 'sg' => array('country' => 'Singapore', 'code' => '+65'), + 'sk' => array('country' => 'Slovakia', 'code' => '+421'), + 'si' => array('country' => 'Slovenia', 'code' => '+386'), + 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), + 'so' => array('country' => 'Somalia', 'code' => '+252'), + 'za' => array('country' => 'South Africa', 'code' => '+27'), + 'kr' => array('country' => 'South Korea', 'code' => '+82'), + 'es' => array('country' => 'Spain', 'code' => '+34'), + 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), + 'sd' => array('country' => 'Sudan', 'code' => '+249'), + 'sr' => array('country' => 'Suriname', 'code' => '+597'), + 'sz' => array('country' => 'Swaziland', 'code' => '+268'), + 'se' => array('country' => 'Sweden', 'code' => '+46'), + 'ch' => array('country' => 'Switzerland', 'code' => '+41'), + 'sy' => array('country' => 'Syria', 'code' => '+963'), + 'tw' => array('country' => 'Taiwan', 'code' => '+886'), + 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), + 'tz' => array('country' => 'Tanzania', 'code' => '+255'), + 'th' => array('country' => 'Thailand', 'code' => '+66'), + 'tg' => array('country' => 'Togo', 'code' => '+228'), + 'tk' => array('country' => 'Tokelau', 'code' => '+690'), + 'to' => array('country' => 'Tonga', 'code' => '+676'), + 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), + 'tn' => array('country' => 'Tunisia', 'code' => '+216'), + 'tr' => array('country' => 'Turkey', 'code' => '+90'), + 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), + 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), + 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), + 'ug' => array('country' => 'Uganda', 'code' => '+256'), + 'ua' => array('country' => 'Ukraine', 'code' => '+380'), + 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), + 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), + 'us' => array('country' => 'United States', 'code' => '+1'), + 'uy' => array('country' => 'Uruguay', 'code' => '+598'), + 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), + 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), + 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), + 'va' => array('country' => 'Vatican City', 'code' => '+39'), + 've' => array('country' => 'Venezuela', 'code' => '+58'), + 'vn' => array('country' => 'Vietnam', 'code' => '+84'), + 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), + 'ye' => array('country' => 'Yemen', 'code' => '+967'), + 'zm' => array('country' => 'Zambia', 'code' => '+260'), + 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), + ); + + if (is_null($cc)) { + return $country_code; + } + elseif (isset($country_code[$cc])) { + return $country_code[$cc]; + } + + return FALSE; +} --- css/cck_phone.css +++ css/cck_phone.css @@ -0,0 +1,35 @@ +/* $Id: cck_phone.css,v 1.2 2010/07/12 09:54:52 ckng Exp $ */ +.cck-phone-field .form-item { + margin: 0; +} + +.cck-phone-column { + float: left; +} +.cck-phone-field-phone { + width: 15em; +} +.cck-phone-field-cc { + width: 25em; +} + +.cck-phone-field-ext { + width: 9em; +} +.cck-phone-extension { + float: left; + margin: 0 .5em; +} +.cck-phone-field-ext .form-item { + float: left; +} + +.cck-phone-settings .form-checkboxes .form-item { + float: left; + width: 33%; +} + +.cck-phone-settings .cck-phone-default-country { + background: #eee; + font-weight: bold; +} --- includes/cc.template.php +++ includes/cc.template.php @@ -0,0 +1,70 @@ + $subaddress)); + return FALSE; + } + // Assign $number_error as FALSE if $number is not valid + if (!empty($number) && $number_error) { + $error = t('%phone_input is not a valid phone number, it should be 10 digits number like "999 999 9999"', array('%phone_input' => $number)); + return FALSE; + } + return TRUE; +} + + +/** + * Cleanup user-entered values for a phone number field for storing to DB. + * + * @param $number + * A single phone number item. + */ +function CC_sanitize_number(&$number) { + // your cleanup like removing trunk prefix + $number = preg_replace('/^([0]*)/', '', $number); +} + + +/** + * Default formatter for international phone number. + * + * @param $number + * Phone number. + */ +function CC_formatter_default($number) { + // Format the phone number and its area code into human readable format + $phone = $number; + + return $phone; +} --- includes/cck_phone_countrycodes.inc +++ includes/cck_phone_countrycodes.inc @@ -0,0 +1,266 @@ + array('country' => 'Afghanistan', 'code' => '+93'), + 'al' => array('country' => 'Albania', 'code' => '+355'), + 'dz' => array('country' => 'Algeria', 'code' => '+213'), + 'as' => array('country' => 'American Samoa', 'code' => '+1'), + 'ad' => array('country' => 'Andorra', 'code' => '+376'), + 'ao' => array('country' => 'Angola', 'code' => '+244'), + 'ai' => array('country' => 'Anguilla', 'code' => '+1'), + 'ag' => array('country' => 'Antigua and Barbuda', 'code' => '+1'), + 'ar' => array('country' => 'Argentina', 'code' => '+54'), + 'am' => array('country' => 'Armenia', 'code' => '+374'), + 'aw' => array('country' => 'Aruba', 'code' => '+297'), + 'au' => array('country' => 'Australia', 'code' => '+61'), + 'at' => array('country' => 'Austria', 'code' => '+43'), + 'az' => array('country' => 'Azerbaijan', 'code' => '+994'), + 'bs' => array('country' => 'Bahamas, The', 'code' => '+1'), + 'bh' => array('country' => 'Bahrain', 'code' => '+973'), + 'bd' => array('country' => 'Bangladesh', 'code' => '+880'), + 'bb' => array('country' => 'Barbados', 'code' => '+1'), + 'by' => array('country' => 'Belarus', 'code' => '+375'), + 'be' => array('country' => 'Belgium', 'code' => '+32'), + 'bz' => array('country' => 'Belize', 'code' => '+501'), + 'bj' => array('country' => 'Benin', 'code' => '+229'), + 'bm' => array('country' => 'Bermuda', 'code' => '+1'), + 'bt' => array('country' => 'Bhutan', 'code' => '+975'), + 'bo' => array('country' => 'Bolivia', 'code' => '+591'), + 'ba' => array('country' => 'Bosnia and Herzegovina', 'code' => '+387'), + 'bw' => array('country' => 'Botswana', 'code' => '+267'), + 'br' => array('country' => 'Brazil', 'code' => '+55'), + 'io' => array('country' => 'British Indian Ocean Territory', 'code' => '+246'), + 'vg' => array('country' => 'British Virgin Islands', 'code' => '+1'), + 'bn' => array('country' => 'Brunei', 'code' => '+673'), + 'bg' => array('country' => 'Bulgaria', 'code' => '+359'), + 'bf' => array('country' => 'Burkina Faso', 'code' => '+226'), + 'bi' => array('country' => 'Burundi', 'code' => '+257'), + 'kh' => array('country' => 'Cambodia', 'code' => '+855'), + 'cm' => array('country' => 'Cameroon', 'code' => '+237'), + 'ca' => array('country' => 'Canada', 'code' => '+1'), + 'cv' => array('country' => 'Cape Verde', 'code' => '+238'), + 'ky' => array('country' => 'Cayman Islands', 'code' => '+1'), + 'cf' => array('country' => 'Central African Republic', 'code' => '+236'), + 'td' => array('country' => 'Chad', 'code' => '+235'), + 'cl' => array('country' => 'Chile', 'code' => '+56'), + 'cn' => array('country' => 'China', 'code' => '+86'), + 'cx' => array('country' => 'Christmas Island', 'code' => '+61'), + 'cc' => array('country' => 'Cocos-Keeling Islands', 'code' => '+61'), + 'co' => array('country' => 'Colombia', 'code' => '+57'), + 'km' => array('country' => 'Comoros', 'code' => '+269'), + 'cg' => array('country' => 'Congo, Republic of the', 'code' => '+242'), + 'cd' => array('country' => 'Congo, Democratic Republic of', 'code' => '+243'), + 'ck' => array('country' => 'Cook Islands', 'code' => '+682'), + 'cr' => array('country' => 'Costa Rica', 'code' => '+506'), + 'hr' => array('country' => 'Croatia', 'code' => '+385'), + 'cu' => array('country' => 'Cuba', 'code' => '+53'), + 'cy' => array('country' => 'Cyprus', 'code' => '+357'), + 'cz' => array('country' => 'Czech Republic', 'code' => '+420'), + 'dk' => array('country' => 'Denmark', 'code' => '+45'), + 'dj' => array('country' => 'Djibouti', 'code' => '+253'), + 'dm' => array('country' => 'Dominica', 'code' => '+1'), + 'do' => array('country' => 'Dominican Republic', 'code' => '+1'), + 'tp' => array('country' => 'East Timor', 'code' => '+670'), + 'ec' => array('country' => 'Ecuador', 'code' => '+593'), + 'eg' => array('country' => 'Egypt', 'code' => '+20'), + 'sv' => array('country' => 'El Salvador', 'code' => '+503'), + 'gq' => array('country' => 'Equatorial Guinea', 'code' => '+240'), + 'er' => array('country' => 'Eritrea', 'code' => '+291'), + 'ee' => array('country' => 'Estonia', 'code' => '+372'), + 'et' => array('country' => 'Ethiopia', 'code' => '+251'), + 'fk' => array('country' => 'Falkland Islands', 'code' => '+500'), + 'fo' => array('country' => 'Faroe Islands', 'code' => '+298'), + 'fj' => array('country' => 'Fiji', 'code' => '+679'), + 'fi' => array('country' => 'Finland', 'code' => '+358'), + 'fr' => array('country' => 'France', 'code' => '+33'), + 'gf' => array('country' => 'French Guiana', 'code' => '+594'), + 'pf' => array('country' => 'French Polynesia', 'code' => '+689'), + 'ga' => array('country' => 'Gabon', 'code' => '+241'), + 'gm' => array('country' => 'Gambia, The', 'code' => '+220'), + 'ge' => array('country' => 'Georgia', 'code' => '+995'), + 'de' => array('country' => 'Germany', 'code' => '+49'), + 'gh' => array('country' => 'Ghana', 'code' => '+233'), + 'gi' => array('country' => 'Gibraltar', 'code' => '+350'), + 'gr' => array('country' => 'Greece', 'code' => '+30'), + 'gl' => array('country' => 'Greenland', 'code' => '+299'), + 'gd' => array('country' => 'Grenada', 'code' => '+1'), + 'gp' => array('country' => 'Guadeloupe', 'code' => '+590'), + 'gu' => array('country' => 'Guam', 'code' => '+1'), + 'gt' => array('country' => 'Guatemala', 'code' => '+502'), + 'gn' => array('country' => 'Guinea', 'code' => '+224'), + 'gw' => array('country' => 'Guinea-Bissau', 'code' => '+245'), + 'gy' => array('country' => 'Guyana', 'code' => '+592'), + 'ht' => array('country' => 'Haiti', 'code' => '+509'), + 'hn' => array('country' => 'Honduras', 'code' => '+504'), + 'hk' => array('country' => 'Hong Kong', 'code' => '+852'), + 'hu' => array('country' => 'Hungary', 'code' => '+36'), + 'is' => array('country' => 'Iceland', 'code' => '+354'), + 'in' => array('country' => 'India', 'code' => '+91'), + 'id' => array('country' => 'Indonesia', 'code' => '+62'), + 'ir' => array('country' => 'Iran', 'code' => '+98'), + 'iq' => array('country' => 'Iraq', 'code' => '+964'), + 'ie' => array('country' => 'Ireland', 'code' => '+353'), + 'il' => array('country' => 'Israel', 'code' => '+972'), + 'it' => array('country' => 'Italy', 'code' => '+39'), + 'ci' => array('country' => 'Ivory Coast', 'code' => '+225'), + 'jm' => array('country' => 'Jamaica', 'code' => '+1'), + 'jp' => array('country' => 'Japan', 'code' => '+81'), + 'jo' => array('country' => 'Jordan', 'code' => '+962'), + 'kz' => array('country' => 'Kazakhstan', 'code' => '+7'), + 'ke' => array('country' => 'Kenya', 'code' => '+254'), + 'ki' => array('country' => 'Kiribati', 'code' => '+686'), + 'kw' => array('country' => 'Kuwait', 'code' => '+965'), + 'kg' => array('country' => 'Kyrgyzstan', 'code' => '+996'), + 'la' => array('country' => 'Laos', 'code' => '+856'), + 'lv' => array('country' => 'Latvia', 'code' => '+371'), + 'lb' => array('country' => 'Lebanon', 'code' => '+961'), + 'ls' => array('country' => 'Lesotho', 'code' => '+266'), + 'lr' => array('country' => 'Liberia', 'code' => '+231'), + 'ly' => array('country' => 'Libya', 'code' => '+218'), + 'li' => array('country' => 'Liechtenstein', 'code' => '+423'), + 'lt' => array('country' => 'Lithuania', 'code' => '+370'), + 'lu' => array('country' => 'Luxembourg', 'code' => '+352'), + 'mo' => array('country' => 'Macau', 'code' => '+853'), + 'mk' => array('country' => 'Macedonia', 'code' => '+389'), + 'mg' => array('country' => 'Madagascar', 'code' => '+261'), + 'mw' => array('country' => 'Malawi', 'code' => '+265'), + 'my' => array('country' => 'Malaysia', 'code' => '+60'), + 'mv' => array('country' => 'Maldives', 'code' => '+960'), + 'ml' => array('country' => 'Mali', 'code' => '+223'), + 'mt' => array('country' => 'Malta', 'code' => '+356'), + 'mh' => array('country' => 'Marshall Islands', 'code' => '+692'), + 'mq' => array('country' => 'Martinique', 'code' => '+596'), + 'mr' => array('country' => 'Mauritania', 'code' => '+222'), + 'mu' => array('country' => 'Mauritius', 'code' => '+230'), + 'yt' => array('country' => 'Mayotte', 'code' => '+269'), + 'mx' => array('country' => 'Mexico', 'code' => '+52'), + 'fm' => array('country' => 'Micronesia, Federated States of', 'code' => '+691'), + 'md' => array('country' => 'Moldova', 'code' => '+373'), + 'mc' => array('country' => 'Monaco', 'code' => '+377'), + 'mn' => array('country' => 'Mongolia', 'code' => '+976'), + 'me' => array('country' => 'Montenegro', 'code' => '+382'), + 'ms' => array('country' => 'Montserrat', 'code' => '+1'), + 'ma' => array('country' => 'Morocco', 'code' => '+212'), + 'mz' => array('country' => 'Mozambique', 'code' => '+258'), + 'mm' => array('country' => 'Myanmar', 'code' => '+95'), + 'na' => array('country' => 'Namibia', 'code' => '+264'), + 'nr' => array('country' => 'Nauru', 'code' => '+674'), + 'np' => array('country' => 'Nepal', 'code' => '+977'), + 'nl' => array('country' => 'Netherlands', 'code' => '+31'), + 'an' => array('country' => 'Netherlands Antilles', 'code' => '+599'), + 'nc' => array('country' => 'New Caledonia', 'code' => '+687'), + 'nz' => array('country' => 'New Zealand', 'code' => '+64'), + 'ni' => array('country' => 'Nicaragua', 'code' => '+505'), + 'ne' => array('country' => 'Niger', 'code' => '+227'), + 'ng' => array('country' => 'Nigeria', 'code' => '+234'), + 'nu' => array('country' => 'Niue', 'code' => '+683'), + 'nf' => array('country' => 'Norfolk Island', 'code' => '+672'), + 'kp' => array('country' => 'North Korea', 'code' => '+850'), + 'mp' => array('country' => 'Northern Mariana Islands', 'code' => '+1'), + 'no' => array('country' => 'Norway', 'code' => '+47'), + 'om' => array('country' => 'Oman', 'code' => '+968'), + 'pk' => array('country' => 'Pakistan', 'code' => '+92'), + 'pw' => array('country' => 'Palau', 'code' => '+680'), + 'ps' => array('country' => 'Palestine', 'code' => '+970'), + 'pa' => array('country' => 'Panama', 'code' => '+507'), + 'pg' => array('country' => 'Papua New Guinea', 'code' => '+675'), + 'py' => array('country' => 'Paraguay', 'code' => '+595'), + 'pe' => array('country' => 'Peru', 'code' => '+51'), + 'ph' => array('country' => 'Philippines', 'code' => '+63'), + 'pl' => array('country' => 'Poland', 'code' => '+48'), + 'pt' => array('country' => 'Portugal', 'code' => '+351'), + 'pr' => array('country' => 'Puerto Rico', 'code' => '+1'), + 'qa' => array('country' => 'Qatar', 'code' => '+974'), + 'ro' => array('country' => 'Romania', 'code' => '+40'), + 'ru' => array('country' => 'Russia', 'code' => '+7'), + 'rw' => array('country' => 'Rwanda', 'code' => '+250'), + 'sh' => array('country' => 'Saint Helena', 'code' => '+290'), + 'kn' => array('country' => 'Saint Kitts and Nevis', 'code' => '+1'), + 'lc' => array('country' => 'Saint Lucia', 'code' => '+1'), + 'pm' => array('country' => 'Saint Pierre and Miquelon', 'code' => '+508'), + 'vc' => array('country' => 'Saint Vincent and the Grenadines', 'code' => '+1'), + 'ws' => array('country' => 'Samoa', 'code' => '+1'), + 'sm' => array('country' => 'San Marino', 'code' => '+378'), + 'st' => array('country' => 'Sao Tome and Principe', 'code' => '+239'), + 'sa' => array('country' => 'Saudi Arabia', 'code' => '+966'), + 'sn' => array('country' => 'Senegal', 'code' => '+221'), + 'rs' => array('country' => 'Serbia', 'code' => '+381'), + 'sc' => array('country' => 'Seychelles', 'code' => '+248'), + 'sl' => array('country' => 'Sierra Leone', 'code' => '+232'), + 'sg' => array('country' => 'Singapore', 'code' => '+65'), + 'sk' => array('country' => 'Slovakia', 'code' => '+421'), + 'si' => array('country' => 'Slovenia', 'code' => '+386'), + 'sb' => array('country' => 'Solomon Islands', 'code' => '+677'), + 'so' => array('country' => 'Somalia', 'code' => '+252'), + 'za' => array('country' => 'South Africa', 'code' => '+27'), + 'kr' => array('country' => 'South Korea', 'code' => '+82'), + 'es' => array('country' => 'Spain', 'code' => '+34'), + 'lk' => array('country' => 'Sri Lanka', 'code' => '+94'), + 'sd' => array('country' => 'Sudan', 'code' => '+249'), + 'sr' => array('country' => 'Suriname', 'code' => '+597'), + 'sz' => array('country' => 'Swaziland', 'code' => '+268'), + 'se' => array('country' => 'Sweden', 'code' => '+46'), + 'ch' => array('country' => 'Switzerland', 'code' => '+41'), + 'sy' => array('country' => 'Syria', 'code' => '+963'), + 'tw' => array('country' => 'Taiwan', 'code' => '+886'), + 'tj' => array('country' => 'Tajikistan', 'code' => '+992'), + 'tz' => array('country' => 'Tanzania', 'code' => '+255'), + 'th' => array('country' => 'Thailand', 'code' => '+66'), + 'tg' => array('country' => 'Togo', 'code' => '+228'), + 'tk' => array('country' => 'Tokelau', 'code' => '+690'), + 'to' => array('country' => 'Tonga', 'code' => '+676'), + 'tt' => array('country' => 'Trinidad and Tobago', 'code' => '+1'), + 'tn' => array('country' => 'Tunisia', 'code' => '+216'), + 'tr' => array('country' => 'Turkey', 'code' => '+90'), + 'tm' => array('country' => 'Turkmenistan', 'code' => '+993'), + 'tc' => array('country' => 'Turks and Caicos Islands', 'code' => '+1'), + 'tv' => array('country' => 'Tuvalu', 'code' => '+688'), + 'ug' => array('country' => 'Uganda', 'code' => '+256'), + 'ua' => array('country' => 'Ukraine', 'code' => '+380'), + 'ae' => array('country' => 'United Arab Emirates', 'code' => '+971'), + 'gb' => array('country' => 'United Kingdom', 'code' => '+44'), + 'us' => array('country' => 'United States', 'code' => '+1'), + 'uy' => array('country' => 'Uruguay', 'code' => '+598'), + 'vi' => array('country' => 'US Virgin Islands', 'code' => '+1'), + 'uz' => array('country' => 'Uzbekistan', 'code' => '+998'), + 'vu' => array('country' => 'Vanuatu', 'code' => '+678'), + 'va' => array('country' => 'Vatican City', 'code' => '+39'), + 've' => array('country' => 'Venezuela', 'code' => '+58'), + 'vn' => array('country' => 'Vietnam', 'code' => '+84'), + 'wf' => array('country' => 'Wallis and Futuna', 'code' => '+681'), + 'ye' => array('country' => 'Yemen', 'code' => '+967'), + 'zm' => array('country' => 'Zambia', 'code' => '+260'), + 'zw' => array('country' => 'Zimbabwe', 'code' => '+263'), + ); + + if (is_null($cc)) { + return $country_code; + } + elseif (isset($country_code[$cc])) { + return $country_code[$cc]; + } + + return FALSE; +} --- includes/phone.ph.inc +++ includes/phone.ph.inc @@ -0,0 +1,108 @@ + 12)) { + $error = t('%phone_input is not a valid phone number, it should have at least 8 digits number like "2 999 9999" and maximum of 12 digits like "12345 999 9999".', array('%phone_input' => $number)); + return FALSE; + } + return TRUE; +} + +/** + * Cleanup user-entered values for a phone number field for storing to DB. + * + * @param $number + * A single phone number item. + */ +function ph_sanitize_number(&$number) { + $number = preg_replace('/^([0]*)/', '', $number); +} + +/** + * Default formatter for international phone number. + * + * @param $number + * Phone number. + */ +function ph_formatter_default($number) { + $regex = "/ + # 5 digit area code. + ( + (\d{5}) # capture 5 digit area code + (\d{3}) # capture first set of numbers in the local number + (\d{4}) # capture second set of numbers in the local number + | + # 4 digit area code. + (\d{4}) # capture 4 digit area code + (\d{3}) # capture first set of numbers in the local number + (\d{4}) # capture second set of numbers in the local number + | + # 3 digit area code. + (\d{3}) # capture 3 digit area code + (\d{3}) # capture first set of numbers in the local number + (\d{4}) # capture second set of numbers in the local number + | + # 2 digit area code. + (\d{2}) # capture 2 digit area code + (\d{3}) # capture first set of numbers in the local number + (\d{4}) # capture second set of numbers in the local number + | + # 1 digit area code. + (\d{1}) # capture 1 digit area code + (\d{3}) # capture first set of numbers in the local number + (\d{4}) # capture second set of numbers in the local number + ) + /x"; + + preg_match($regex, $number, $matches); + if (isset($matches[14]) && !empty($matches[14])) { + $area = $matches[14]; + $head_num = $matches[15]; + $tail_num = $matches[16]; + } + elseif (isset($matches[11]) && !empty($matches[11])) { + $area = $matches[11]; + $head_num = $matches[12]; + $tail_num = $matches[13]; + } + elseif (isset($matches[8]) && !empty($matches[8])) { + $area = $matches[8]; + $head_num = $matches[9]; + $tail_num = $matches[10]; + } + elseif (isset($matches[5]) && !empty($matches[5])) { + $area = $matches[5]; + $head_num = $matches[6]; + $tail_num = $matches[7]; + } + else { + $area = $matches[2]; + $head_num = $matches[3]; + $tail_num = $matches[4]; + } + return '(' . $area . ') ' . $head_num . '-' . $tail_num; +} --- js/cck_phone.manage_field.js +++ js/cck_phone.manage_field.js @@ -0,0 +1,113 @@ +// $Id: cck_phone.js,v 1.2 2010/07/12 09:54:52 ckng Exp $ + +Drupal.PhoneNumber = Drupal.PhoneNumber || {}; + +/** + * Filters checkboxes based on their label. + * This code is shamelessly taken from checkbox_filter + */ +Drupal.PhoneNumber.filter = function() { + var field = $(this); + var checkboxes = $('.form-checkboxes .form-item', field.parent().parent()); + var found = false; + var label = ""; + var option = null; + for (var i = 0; i < checkboxes.length; i++) { + option = checkboxes.eq(i); + label = Drupal.PhoneNumber.trim(option.text()); + if (label.toUpperCase().indexOf(field.val().toUpperCase()) < 0) { + option.hide(); + } else { + option.show(); + } + } +} + +/** + * Trims whitespace from strings + */ +Drupal.PhoneNumber.trim = function(str) { + var str = str.replace(/^\s\s*/, ''), + ws = /\s/, + i = str.length; + while (ws.test(str.charAt(--i))); + return str.slice(0, i + 1); +} + +/** + * Check/Uncheck all checkboxes + */ +Drupal.PhoneNumber.checkall = function(e) { + var field = $(this); + var checkboxes = $('.form-checkboxes .form-item:visible .form-checkbox', field.parent().parent()); + + var checked = (field.text() == Drupal.t('Select all')); + if (checked) { + checkboxes.attr('checked', true); + field.text(Drupal.t('Deselect all')); + } + else { + checkboxes.attr('checked', false); + Drupal.PhoneNumber.checkDefault(); + field.text(Drupal.t('Select all')); + } +} + +/** + * Country selection should include default country code by default. + */ +Drupal.PhoneNumber.checkDefault = function(e) { + var defaultCC = $('#edit-default-country').val(); + var span = $('').append(Drupal.t('Default')); + + if ($('.cck-phone-default-country').find('.form-checkbox').val() == defaultCC) { + $('#edit-country-selection-' + defaultCC) + .attr('checked', 'checked'); + } + else { + $('.cck-phone-default-country') + .removeClass('cck-phone-default-country') + .find('span.default-cc').remove(); + + + $('#edit-country-selection-' + defaultCC) + .attr('checked', 'checked') + .parents('.form-item:first') + .addClass('cck-phone-default-country') + .append(span); + } +} + +/** + * Attach a filtering textfield to checkboxes. + */ +Drupal.behaviors.PhoneNumber = function (context) { + // Toggle collapsible on selection + $('#edit-all-country-codes').change(function() { + if ($(this).attr('checked')) { + $('fieldset.cck-phone-settings').addClass('collapsed'); + } + else { + $('fieldset.cck-phone-settings').removeClass('collapsed'); + } + }); + $('#edit-all-country-codes').trigger('change'); + + // Ensure the new default country is checked + $('#edit-default-country, .cck-phone-settings .form-checkboxes').bind('change', Drupal.PhoneNumber.checkDefault); + $('#edit-default-country').trigger('change'); + $('form#content-field-edit-form').submit(Drupal.PhoneNumber.checkDefault); + + + // Filter for countries + var form = '
' + + ' ' + + ' ' + + '
' + + ''; + $('.cck-phone-settings .form-checkboxes', context).before(form); + $('input.cck-phone-filter').bind('keyup', Drupal.PhoneNumber.filter); + $('a.cck-phone-check').bind('click', Drupal.PhoneNumber.checkall); +} --- theme/phone-field-view.tpl.php +++ theme/phone-field-view.tpl.php @@ -0,0 +1,27 @@ + + + > + + + + + + +