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	24 Jul 2010 07:07:34 -0000
@@ -3,341 +3,571 @@
 
 /**
  * @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_subaddress'  => TRUE,
+        'phone_extra'       => TRUE,
+        'phone_rel'         => FALSE,
+        '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_subaddress'] = array(
+    '#type'          => 'checkbox',
+    '#default_value' => $settings['phone_subaddress'],    
+    '#title'         => t('Add extension number, ISDN subaddress, fax\'s T33 subaddress or modem\'s parameters/recommended parameters (!ref)', array('!ref' => l('URLs for Telephone Calls', 'http://tools.ietf.org/html/rfc2806'))),
+    '#weight'        => 3,
+  );
+  $form['phone_extra'] = array(
+    '#type'          => 'checkbox',
+    '#default_value' => $settings['phone_extra'],    
+    '#title'         => t('Add extra phone number\'s description'),
+    '#weight'        => 3,
+  );
+  $form['phone_rel'] = array(
+    '#type'          => 'checkbox',
+    '#default_value' => $settings['phone_rel'],    
+    '#title'         => t('Add manually the relation value placed at rel="[relation value]" of anchor tag'),
+    '#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.'),
+      ),
+      'subaddress_type' => array(
+        'type'        => 'varchar',
+        'length'      => 8,
+        'not null'    => FALSE,
+        'description' => t('Subaddress type: telephone/fax\'s extension number (ext), ISDN subaddress (isub), fax\'s T33 subaddress (tsub), modem\'s parameters (type)/recommended parameters (rec). Reference: http://tools.ietf.org/html/rfc2806.'),
+      ),
+      'subaddress_value' => array(
+        'type'        => 'varchar',
+        'length'      => 128,
+        'not null'    => FALSE,
+        'description' => t('Subaddress value for telephone/fax\'s extension number (ext), ISDN subaddress (isub), fax\'s T33 subaddress (tsub), modem\'s parameters (type)/recommended parameters (rec). Reference: http://tools.ietf.org/html/rfc2806.'),
+      ),
+      '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).'),
+      ),
+      'rel_val' => array(
+        'type'        => 'varchar',
+        'length'      => 32,
+        'not null'    => FALSE,
+        'description' => t('The relation value placed at rel="[rel_value]" of anchor tag (in support for RDFA). If empty, it will have a default of "foaf:phone".'),
+      ),
+      '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 <em>*</em> 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);
+      if (!empty($subaddress_value)) {
+        $subaddress_error = FALSE;
+        $subaddress_type  = $item['type'];
+        switch ($subaddress_type) {
+          case 'Voice':
+          case 'Home':
+          case 'Msg':
+          case 'Work':
+          case 'Pref':
+          case 'Cell':
+          case 'Video':
+          case 'Pager':
+          case 'Car':
+          case 'PCS':
+          case 'BBS':
+            if ($item['subaddress_type'] != 'ext') {
+              $subaddress_error = TRUE;
+            }
+            break;
+          case 'Fax':
+            if ($item['subaddress_type'] != 'ext' && $item['subaddress_type'] != 'isub' && $item['subaddress_type'] != 'tsub') {
+              $subaddress_error = TRUE;
+            }
+            break;
+          case 'Modem':
+            if ($item['subaddress_type'] != 'type' && $item['subaddress_type'] != 'rec') {
+              $subaddress_error = TRUE;
+            }
+            break;
+          case 'ISDN':
+            if ($item['subaddress_type'] != 'isub') {
+              $subaddress_error = TRUE;
+            }
+            break;
         }
-      }
-      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));
+        if ($subaddress_error) {
+          $errors[$field_name][$langcode][$delta][] = array(
+            'error'   => 'subaddress_type',
+            'message' => t('Subaddress type is not valid with %type phone type.', array('%type' => $item['type'])),
+          );
+        }
+        if ($item['subaddress_type'] != 'ext') {
+          $subaddress_value = preg_replace('/[^0-9]/', '', $subaddress_value);
+          if (drupal_strlen($subaddress_value) > CCK_PHONE_EXTENSION_MAX_LENGTH) {
+            $errors[$field_name][$langcode][$delta][] = array(
+              'error'   => 'subaddress_value',
+              'message' => t('Extension number should not exceed %max.', array('%max' => CCK_PHONE_EXTENSION_MAX_LENGTH)),
+            );
+          }
+          elseif ($has_cc) {
+            if (!$validate_function('', $subaddress_value, $error_message, $subaddress_type)) {
+              $errors[$field_name][$langcode][$delta][] = array(
+                'error'   => 'value',
+                'message' => $error_message,
+              );
+            }
+          }
         }
       }
-      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']));
+    $rel   = check_plain($item['rel_val']);
+    $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]['subaddress_value'] = check_plain($items[$delta]['subaddress_value']);
+    $items[$delta]['extra']   = t($items[$delta]['extra']);
+    $items[$delta]['type']    = t($items[$delta]['type']);
+    $items[$delta]['rel_val'] = empty($rel) ? 'foaf:phone' : $rel;    
+    $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('<em> ext.</em> @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_subaddress']) {
+    $subaddress = array(
+      'ext'  => t('Extension number'),
+      'isub' => t('ISDN subaddress'),
+      'tsub' => t('T33 subaddress'),
+      'type' => t('Modem parameters'),
+      'rec'  => t('Modem recommended parameters'),
+    );
+    $elements['phone_field']['phone_advance']['subaddress'] = array(
+      '#type'        => 'item',
+      '#title'       => t('Subaddress'),
+      '#description' => t('Select subaddress type from the selectbox and enter its value in the textfield.'),      
+    );
+    $elements['phone_field']['phone_advance']['subaddress']['subaddress_type'] = array(
+      '#type'           => 'select',
+      '#title'          => t('Subaddress type'),
+      '#options'        => $subaddress,
+      '#default_value'  => isset($items[$delta]['subaddress_type']) ? $items[$delta]['subaddress_type'] : 'ext',
+      '#parents'        => array($field_name, $langcode, $delta, 'subaddress_type'),
+      '#suffix'         => '&nbsp;',
+      '#theme_wrappers' => array(),
+    );
+    $elements['phone_field']['phone_advance']['subaddress']['subaddress_value'] = array(
+      '#type'           => 'textfield',
+      '#title'          => t('Subaddress'),
+      '#size'           => 20,
+      '#maxlength'      => 128,
+      '#default_value'  => isset($items[$delta]['subaddress_value']) ? $items[$delta]['subaddress_value'] : '',
+      '#parents'        => array($field_name, $langcode, $delta, 'subaddress_value'),
+      '#theme_wrappers' => array(),
+    );
+  }
+  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']),
+    );
+  }
+  if ($instance['settings']['phone_rel']) {
+    $elements['phone_field']['phone_advance']['rel_val'] = array(
+      '#type'           => 'textfield',
+      '#title'          => t('Relation value'),
+      '#size'           => 60,
+      '#maxlength'      => 255,
+      '#default_value'  => isset($items[$delta]['rel_val']) ? $items[$delta]['rel_val'] : '',
+      '#parents'        => array($field_name, $langcode, $delta, 'rel_val'),
+      '#description'    => t($field['columns']['rel_val']['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 = '<a href="tel:' . $tel . '">' . $phone . '</a>';
-  }
-
-  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,
+      'subaddress_type'  => $item['subaddress_type'],
+      'subaddress_value' => $item['subaddress_value'],
+      'type'       => $item['type'],
+      'extra'      => $item['extra'],
+      'value_attr' => array('class' => array('value'), 'rel' => array($item['rel_val'])),
+      '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 +580,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 +613,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 .= '<br />'. 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 .= '<br />'. 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 = '<div class="form-item"';
-  if (!empty($element['#id'])) {
-    $output .= ' id="'. $element['#id'] .'-wrapper"';
-  }
-  $output .= ">\n";
-
-  $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
-
-  if (!empty($element['#title'])) {
-    $title = $element['#title'];
-    if (!empty($element['number']['#id'])) {
-      $output .= ' <label for="'. $element['number']['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
-    }
-    else {
-      $output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
-    }
-  }
-
-  $output .= '<div class="cck-phone-field clear-block">';
-  if (isset($element['number'])) {
-    $output .= '<div class="cck-phone-field-phone cck-phone-column">'. theme('textfield', $element['number']) .'</div>';
-  }
-  if (isset($element['extension'])) {
-    $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : '';
-    $output .= '<div class="cck-phone-field-ext cck-phone-column">'. $prefix . theme('textfield', $element['extension']) .'</div>';
-  }
-  $output .= '<div class="cck-phone-field-cc cck-phone-column">'. theme('select', $element['country_codes']) .'</div>';
-  $output .= '</div></div>';
-
-  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' => '<div class="cck-phone-extension">'. t('ext') .'</div>',
-    );
-  }
-
-  $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:<phone number>;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,10723 @@
+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 <em>*</em> 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('<em> ext.</em> @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 = '<a href="tel:' . $tel . '">' . $phone . '</a>';
+-  }
+-
+-  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 .= '<br />'. 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 .= '<br />'. 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 = '<div class="form-item"';
+-  if (!empty($element['#id'])) {
+-    $output .= ' id="'. $element['#id'] .'-wrapper"';
+-  }
+-  $output .= ">\n";
+-
+-  $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
+-
+-  if (!empty($element['#title'])) {
+-    $title = $element['#title'];
+-    if (!empty($element['number']['#id'])) {
+-      $output .= ' <label for="'. $element['number']['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
+-    }
+-    else {
+-      $output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
+-    }
+-  }
+-
+-  $output .= '<div class="cck-phone-field clear-block">';
+-  if (isset($element['number'])) {
+-    $output .= '<div class="cck-phone-field-phone cck-phone-column">'. theme('textfield', $element['number']) .'</div>';
+-  }
+-  if (isset($element['extension'])) {
+-    $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : '';
+-    $output .= '<div class="cck-phone-field-ext cck-phone-column">'. $prefix . theme('textfield', $element['extension']) .'</div>';
+-  }
+-  $output .= '<div class="cck-phone-field-cc cck-phone-column">'. theme('select', $element['country_codes']) .'</div>';
+-  $output .= '</div></div>';
+-
+-  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' => '<div class="cck-phone-extension">'. t('ext') .'</div>',
+-    );
+-  }
+-
+-  $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:<phone number>;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 <em>*</em> 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('<em> ext.</em> @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 = '<a href="tel:' . $tel . '">' . $phone . '</a>';
++-  }
++-
++-  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 .= '<br />'. 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 .= '<br />'. 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 = '<div class="form-item"';
++-  if (!empty($element['#id'])) {
++-    $output .= ' id="'. $element['#id'] .'-wrapper"';
++-  }
++-  $output .= ">\n";
++-
++-  $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
++-
++-  if (!empty($element['#title'])) {
++-    $title = $element['#title'];
++-    if (!empty($element['number']['#id'])) {
++-      $output .= ' <label for="'. $element['number']['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
++-    }
++-    else {
++-      $output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
++-    }
++-  }
++-
++-  $output .= '<div class="cck-phone-field clear-block">';
++-  if (isset($element['number'])) {
++-    $output .= '<div class="cck-phone-field-phone cck-phone-column">'. theme('textfield', $element['number']) .'</div>';
++-  }
++-  if (isset($element['extension'])) {
++-    $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : '';
++-    $output .= '<div class="cck-phone-field-ext cck-phone-column">'. $prefix . theme('textfield', $element['extension']) .'</div>';
++-  }
++-  $output .= '<div class="cck-phone-field-cc cck-phone-column">'. theme('select', $element['country_codes']) .'</div>';
++-  $output .= '</div></div>';
++-
++-  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' => '<div class="cck-phone-extension">'. t('ext') .'</div>',
++-    );
++-  }
++-
++-  $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:<phone number>;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 <em>*</em> 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('<em> ext.</em> @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 = '<a href="tel:' . $tel . '">' . $phone . '</a>';
+++-  }
+++-
+++-  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 .= '<br />'. 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 .= '<br />'. 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 = '<div class="form-item"';
+++-  if (!empty($element['#id'])) {
+++-    $output .= ' id="'. $element['#id'] .'-wrapper"';
+++-  }
+++-  $output .= ">\n";
+++-
+++-  $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
+++-
+++-  if (!empty($element['#title'])) {
+++-    $title = $element['#title'];
+++-    if (!empty($element['number']['#id'])) {
+++-      $output .= ' <label for="'. $element['number']['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
+++-    }
+++-    else {
+++-      $output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
+++-    }
+++-  }
+++-
+++-  $output .= '<div class="cck-phone-field clear-block">';
+++-  if (isset($element['number'])) {
+++-    $output .= '<div class="cck-phone-field-phone cck-phone-column">'. theme('textfield', $element['number']) .'</div>';
+++-  }
+++-  if (isset($element['extension'])) {
+++-    $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : '';
+++-    $output .= '<div class="cck-phone-field-ext cck-phone-column">'. $prefix . theme('textfield', $element['extension']) .'</div>';
+++-  }
+++-  $output .= '<div class="cck-phone-field-cc cck-phone-column">'. theme('select', $element['country_codes']) .'</div>';
+++-  $output .= '</div></div>';
+++-
+++-  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' => '<div class="cck-phone-extension">'. t('ext') .'</div>',
+++-    );
+++-  }
+++-
+++-  $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:<phone number>;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 <em>*</em> 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('<em> ext.</em> @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 = '<a href="tel:' . $tel . '">' . $phone . '</a>';
++++-  }
++++-
++++-  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 .= '<br />'. 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 .= '<br />'. 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 = '<div class="form-item"';
++++-  if (!empty($element['#id'])) {
++++-    $output .= ' id="'. $element['#id'] .'-wrapper"';
++++-  }
++++-  $output .= ">\n";
++++-
++++-  $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
++++-
++++-  if (!empty($element['#title'])) {
++++-    $title = $element['#title'];
++++-    if (!empty($element['number']['#id'])) {
++++-      $output .= ' <label for="'. $element['number']['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
++++-    }
++++-    else {
++++-      $output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
++++-    }
++++-  }
++++-
++++-  $output .= '<div class="cck-phone-field clear-block">';
++++-  if (isset($element['number'])) {
++++-    $output .= '<div class="cck-phone-field-phone cck-phone-column">'. theme('textfield', $element['number']) .'</div>';
++++-  }
++++-  if (isset($element['extension'])) {
++++-    $prefix = isset($element['extension']['#prefix']) ? $element['extension']['#prefix'] : '';
++++-    $output .= '<div class="cck-phone-field-ext cck-phone-column">'. $prefix . theme('textfield', $element['extension']) .'</div>';
++++-  }
++++-  $output .= '<div class="cck-phone-field-cc cck-phone-column">'. theme('select', $element['country_codes']) .'</div>';
++++-  $output .= '</div></div>';
++++-
++++-  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' => '<div class="cck-phone-extension">'. t('ext') .'</div>',
++++-    );
++++-  }
++++-
++++-  $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:<phone number>;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 @@
+++++<?php
+++++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+++++
+++++/**
+++++ * @file
+++++ * Defines country codes for Phone Number.
+++++ * Provide country name and international codes per country codes.
+++++ */
+++++
+++++/**
+++++ * Get all the country codes for supported countries.
+++++ *
+++++ * @param $cc
+++++ *   Optional, two character country code. If this is ommitted all country codes
+++++ *   will be returned.
+++++ * @return
+++++ *   If no country code is provided an array keyed by country code, values are
+++++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+++++ *   FALSE will be returned. If the country code is valid the country code for
+++++ *   that country will be returned.
+++++ */
+++++function cck_phone_countrycodes($cc = NULL) {
+++++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+++++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+++++  static $country_code = array(
+++++    'af' => 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 @@
+++++<?php
+++++// $Id: API.php,v 1.3 2010/07/12 09:54:52 ckng Exp $
+++++
+++++/**
+++++ * @file
+++++ * Phone Number custom country API
+++++ *
+++++ * 'CC' will be used throughout this document to indicate country code
+++++ * abbreviation. You should replace it with the correct country code
+++++ * in the following functions name. For full list of country code
+++++ * abbreviation, refer to the 2 alphabet list in the countries.txt.
+++++ */
+++++
+++++
+++++/**
+++++ * Validate country level phone number.
+++++ *
+++++ * @param $number
+++++ *   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
+++++ *   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 this country, FALSE otherwise.
+++++ */
+++++function CC_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+++++  // Assign $subaddress_error as FALSE if $subaddress is not valid
+++++  if (!empty($subaddress) && $subaddress_error) {
+++++    $error = t('%subaddress is not a valid extension number', array('%subaddress' => $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 @@
+++++<?php
+++++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+++++
+++++/**
+++++ * @file
+++++ * Defines country codes for Phone Number.
+++++ * Provide country name and international codes per country codes.
+++++ */
+++++
+++++/**
+++++ * Get all the country codes for supported countries.
+++++ *
+++++ * @param $cc
+++++ *   Optional, two character country code. If this is ommitted all country codes
+++++ *   will be returned.
+++++ * @return
+++++ *   If no country code is provided an array keyed by country code, values are
+++++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+++++ *   FALSE will be returned. If the country code is valid the country code for
+++++ *   that country will be returned.
+++++ */
+++++function cck_phone_countrycodes($cc = NULL) {
+++++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+++++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+++++  static $country_code = array(
+++++    'af' => 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 @@
+++++<?php
+++++// $Id$
+++++
+++++/**
+++++ * @file
+++++ * Phone number field for Philippine phone numbers.
+++++ */
+++++
+++++/**
+++++ * Validate country level phone number.
+++++ *
+++++ * @param $number
+++++ *   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
+++++ *   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 this country, FALSE otherwise.
+++++ */
+++++function ph_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+++++  ph_sanitize_number($number);
+++++  if (!empty($number) && (drupal_strlen($number) < 8 || drupal_strlen($number) > 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 = $('<span class="default-cc"></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 = '<div class="form-item">'
+++++           + '  <label>' + Drupal.t('Filter') + ':</label> '
+++++           + '  <input class="cck-phone-filter" type="text" size="16" />'
+++++           + '</div>'
+++++           + '<div class="form-item">'
+++++           + '  <a class="cck-phone-check" href="javascript://">' + Drupal.t('Select all') + '</a>'
+++++           + '</div>';
+++++  $('.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 @@
+++++<?php
+++++// $Id$
+++++/**
+++++ * @file phone-field-view.tpl.php
+++++ * Default theme implementation for rendering phone number field.
+++++ *
+++++ * Available variables:
+++++ * - $phone: An associative array containing:
+++++ * -- value: Formatted phone number.
+++++ * -- int_code: International country calling code.
+++++ * -- tel_value: Formatted phone number for tel URI.
+++++ *
+++++ * @ingroup themeable
+++++ */
+++++?>
+++++<span class="tel">
+++++  <a href="tel:<?php print $phone['tel_value']; ?>">
+++++    <?php print '+' . $phone['int_code'] . ' ' . $phone['value']; ?>
+++++  </a>
+++++</span>
++++
++++
+++
+++--- cck_phone_countrycodes.inc.tortoise.removed
++++++ cck_phone_countrycodes.inc.tortoise.removed
+++@@ -0,0 +1,266 @@
++++<?php
++++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
++++
++++/**
++++ * @file
++++ * Defines country codes for Phone Number.
++++ * Provide country name and international codes per country codes.
++++ */
++++
++++/**
++++ * Get all the country codes for supported countries.
++++ *
++++ * @param $cc
++++ *   Optional, two character country code. If this is ommitted all country codes
++++ *   will be returned.
++++ * @return
++++ *   If no country code is provided an array keyed by country code, values are
++++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
++++ *   FALSE will be returned. If the country code is valid the country code for
++++ *   that country will be returned.
++++ */
++++function cck_phone_countrycodes($cc = NULL) {
++++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
++++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
++++  static $country_code = array(
++++    'af' => 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 @@
++++<?php
++++// $Id: API.php,v 1.3 2010/07/12 09:54:52 ckng Exp $
++++
++++/**
++++ * @file
++++ * Phone Number custom country API
++++ *
++++ * 'CC' will be used throughout this document to indicate country code
++++ * abbreviation. You should replace it with the correct country code
++++ * in the following functions name. For full list of country code
++++ * abbreviation, refer to the 2 alphabet list in the countries.txt.
++++ */
++++
++++
++++/**
++++ * Validate country level phone number.
++++ *
++++ * @param $number
++++ *   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
++++ *   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 this country, FALSE otherwise.
++++ */
++++function CC_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
++++  // Assign $subaddress_error as FALSE if $subaddress is not valid
++++  if (!empty($subaddress) && $subaddress_error) {
++++    $error = t('%subaddress is not a valid extension number', array('%subaddress' => $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 @@
++++<?php
++++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
++++
++++/**
++++ * @file
++++ * Defines country codes for Phone Number.
++++ * Provide country name and international codes per country codes.
++++ */
++++
++++/**
++++ * Get all the country codes for supported countries.
++++ *
++++ * @param $cc
++++ *   Optional, two character country code. If this is ommitted all country codes
++++ *   will be returned.
++++ * @return
++++ *   If no country code is provided an array keyed by country code, values are
++++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
++++ *   FALSE will be returned. If the country code is valid the country code for
++++ *   that country will be returned.
++++ */
++++function cck_phone_countrycodes($cc = NULL) {
++++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
++++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
++++  static $country_code = array(
++++    'af' => 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 @@
++++<?php
++++// $Id$
++++
++++/**
++++ * @file
++++ * Phone number field for Philippine phone numbers.
++++ */
++++
++++/**
++++ * Validate country level phone number.
++++ *
++++ * @param $number
++++ *   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
++++ *   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 this country, FALSE otherwise.
++++ */
++++function ph_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
++++  ph_sanitize_number($number);
++++  if (!empty($number) && (drupal_strlen($number) < 8 || drupal_strlen($number) > 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 = $('<span class="default-cc"></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 = '<div class="form-item">'
++++           + '  <label>' + Drupal.t('Filter') + ':</label> '
++++           + '  <input class="cck-phone-filter" type="text" size="16" />'
++++           + '</div>'
++++           + '<div class="form-item">'
++++           + '  <a class="cck-phone-check" href="javascript://">' + Drupal.t('Select all') + '</a>'
++++           + '</div>';
++++  $('.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 @@
++++<?php
++++// $Id$
++++/**
++++ * @file phone-field-view.tpl.php
++++ * Default theme implementation for rendering phone number field.
++++ *
++++ * Available variables:
++++ * - $phone: An associative array containing:
++++ * -- value: Formatted phone number.
++++ * -- int_code: International country calling code.
++++ * -- tel_value: Formatted phone number for tel URI.
++++ *
++++ * @ingroup themeable
++++ */
++++?>
++++<span class="tel">
++++  <a href="tel:<?php print $phone['tel_value']; ?>">
++++    <?php print '+' . $phone['int_code'] . ' ' . $phone['value']; ?>
++++  </a>
++++</span>
+++
+++
++
++--- cck_phone_countrycodes.inc.tortoise.removed
+++++ cck_phone_countrycodes.inc.tortoise.removed
++@@ -0,0 +1,266 @@
+++<?php
+++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+++
+++/**
+++ * @file
+++ * Defines country codes for Phone Number.
+++ * Provide country name and international codes per country codes.
+++ */
+++
+++/**
+++ * Get all the country codes for supported countries.
+++ *
+++ * @param $cc
+++ *   Optional, two character country code. If this is ommitted all country codes
+++ *   will be returned.
+++ * @return
+++ *   If no country code is provided an array keyed by country code, values are
+++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+++ *   FALSE will be returned. If the country code is valid the country code for
+++ *   that country will be returned.
+++ */
+++function cck_phone_countrycodes($cc = NULL) {
+++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+++  static $country_code = array(
+++    'af' => 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 @@
+++<?php
+++// $Id: API.php,v 1.3 2010/07/12 09:54:52 ckng Exp $
+++
+++/**
+++ * @file
+++ * Phone Number custom country API
+++ *
+++ * 'CC' will be used throughout this document to indicate country code
+++ * abbreviation. You should replace it with the correct country code
+++ * in the following functions name. For full list of country code
+++ * abbreviation, refer to the 2 alphabet list in the countries.txt.
+++ */
+++
+++
+++/**
+++ * Validate country level phone number.
+++ *
+++ * @param $number
+++ *   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
+++ *   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 this country, FALSE otherwise.
+++ */
+++function CC_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+++  // Assign $subaddress_error as FALSE if $subaddress is not valid
+++  if (!empty($subaddress) && $subaddress_error) {
+++    $error = t('%subaddress is not a valid extension number', array('%subaddress' => $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 @@
+++<?php
+++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+++
+++/**
+++ * @file
+++ * Defines country codes for Phone Number.
+++ * Provide country name and international codes per country codes.
+++ */
+++
+++/**
+++ * Get all the country codes for supported countries.
+++ *
+++ * @param $cc
+++ *   Optional, two character country code. If this is ommitted all country codes
+++ *   will be returned.
+++ * @return
+++ *   If no country code is provided an array keyed by country code, values are
+++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+++ *   FALSE will be returned. If the country code is valid the country code for
+++ *   that country will be returned.
+++ */
+++function cck_phone_countrycodes($cc = NULL) {
+++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+++  static $country_code = array(
+++    'af' => 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 @@
+++<?php
+++// $Id$
+++
+++/**
+++ * @file
+++ * Phone number field for Philippine phone numbers.
+++ */
+++
+++/**
+++ * Validate country level phone number.
+++ *
+++ * @param $number
+++ *   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
+++ *   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 this country, FALSE otherwise.
+++ */
+++function ph_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+++  ph_sanitize_number($number);
+++  if (!empty($number) && (drupal_strlen($number) < 8 || drupal_strlen($number) > 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 = $('<span class="default-cc"></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 = '<div class="form-item">'
+++           + '  <label>' + Drupal.t('Filter') + ':</label> '
+++           + '  <input class="cck-phone-filter" type="text" size="16" />'
+++           + '</div>'
+++           + '<div class="form-item">'
+++           + '  <a class="cck-phone-check" href="javascript://">' + Drupal.t('Select all') + '</a>'
+++           + '</div>';
+++  $('.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 @@
+++<?php
+++// $Id$
+++/**
+++ * @file phone-field-view.tpl.php
+++ * Default theme implementation for rendering phone number field.
+++ *
+++ * Available variables:
+++ * - $phone: An associative array containing:
+++ * -- value: Formatted phone number.
+++ * -- int_code: International country calling code.
+++ * -- tel_value: Formatted phone number for tel URI.
+++ * -- type: hCard microformat property indicating the nature of the phone.
+++ * -- type_attr: Attributes of type item.
+++ * -- extra: Annotation or extra phone number's description.
+++ *
+++ * @ingroup themeable
+++ */
+++?>
+++<span class="tel">
+++  <span <?php print drupal_attributes($phone['type_attr']); ?>><?php print $phone['type']; ?></span>
+++  <a href="tel:<?php print $phone['tel_value']; ?>">
+++    <?php print '+' . $phone['int_code'] . ' ' . $phone['value']; ?>
+++  </a>
+++  <?php if ($phone['extra']): ?>
+++  <span><?php print $phone['extra']; ?></span>
+++  <?php endif; ?>
+++</span>
++
++
+
+--- cck_phone_countrycodes.inc.tortoise.removed
++++ cck_phone_countrycodes.inc.tortoise.removed
+@@ -0,0 +1,266 @@
++<?php
++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
++
++/**
++ * @file
++ * Defines country codes for Phone Number.
++ * Provide country name and international codes per country codes.
++ */
++
++/**
++ * Get all the country codes for supported countries.
++ *
++ * @param $cc
++ *   Optional, two character country code. If this is ommitted all country codes
++ *   will be returned.
++ * @return
++ *   If no country code is provided an array keyed by country code, values are
++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
++ *   FALSE will be returned. If the country code is valid the country code for
++ *   that country will be returned.
++ */
++function cck_phone_countrycodes($cc = NULL) {
++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
++  static $country_code = array(
++    'af' => 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 @@
++<?php
++// $Id: API.php,v 1.3 2010/07/12 09:54:52 ckng Exp $
++
++/**
++ * @file
++ * Phone Number custom country API
++ *
++ * 'CC' will be used throughout this document to indicate country code
++ * abbreviation. You should replace it with the correct country code
++ * in the following functions name. For full list of country code
++ * abbreviation, refer to the 2 alphabet list in the countries.txt.
++ */
++
++
++/**
++ * Validate country level phone number.
++ *
++ * @param $number
++ *   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
++ *   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 this country, FALSE otherwise.
++ */
++function CC_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
++  // Assign $subaddress_error as FALSE if $subaddress is not valid
++  if (!empty($subaddress) && $subaddress_error) {
++    $error = t('%subaddress is not a valid extension number', array('%subaddress' => $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 @@
++<?php
++// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
++
++/**
++ * @file
++ * Defines country codes for Phone Number.
++ * Provide country name and international codes per country codes.
++ */
++
++/**
++ * Get all the country codes for supported countries.
++ *
++ * @param $cc
++ *   Optional, two character country code. If this is ommitted all country codes
++ *   will be returned.
++ * @return
++ *   If no country code is provided an array keyed by country code, values are
++ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
++ *   FALSE will be returned. If the country code is valid the country code for
++ *   that country will be returned.
++ */
++function cck_phone_countrycodes($cc = NULL) {
++  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
++  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
++  static $country_code = array(
++    'af' => 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 @@
++<?php
++// $Id$
++
++/**
++ * @file
++ * Phone number field for Philippine phone numbers.
++ */
++
++/**
++ * Validate country level phone number.
++ *
++ * @param $number
++ *   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
++ *   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 this country, FALSE otherwise.
++ */
++function ph_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
++  ph_sanitize_number($number);
++  if (!empty($number) && (drupal_strlen($number) < 8 || drupal_strlen($number) > 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 = $('<span class="default-cc"></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 = '<div class="form-item">'
++           + '  <label>' + Drupal.t('Filter') + ':</label> '
++           + '  <input class="cck-phone-filter" type="text" size="16" />'
++           + '</div>'
++           + '<div class="form-item">'
++           + '  <a class="cck-phone-check" href="javascript://">' + Drupal.t('Select all') + '</a>'
++           + '</div>';
++  $('.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 @@
++<?php
++// $Id$
++/**
++ * @file phone-field-view.tpl.php
++ * Default theme implementation for rendering phone number field.
++ *
++ * Available variables:
++ * - $phone: An associative array containing:
++ * -- value: Formatted phone number.
++ * -- int_code: International country calling code.
++ * -- tel_value: Formatted phone number for tel URI.
++ * -- type: hCard microformat property indicating the nature of the phone.
++ * -- type_attr: Attributes of type item.
++ * -- extra: Annotation or extra phone number's description.
++ *
++ * @ingroup themeable
++ */
++?>
++<span class="tel">
++  <span <?php print drupal_attributes($phone['type_attr']); ?>><?php print $phone['type']; ?></span>
++  <a href="tel:<?php print $phone['tel_value']; ?>">
++    <?php print '+' . $phone['int_code'] . ' ' . $phone['value']; ?>
++  </a>
++  <?php if ($phone['extra']): ?>
++  <span><?php print $phone['extra']; ?></span>
++  <?php endif; ?>
++</span>
+
+

--- cck_phone_countrycodes.inc.tortoise.removed
+++ cck_phone_countrycodes.inc.tortoise.removed
@@ -0,0 +1,266 @@
+<?php
+// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+
+/**
+ * @file
+ * Defines country codes for Phone Number.
+ * Provide country name and international codes per country codes.
+ */
+
+/**
+ * Get all the country codes for supported countries.
+ *
+ * @param $cc
+ *   Optional, two character country code. If this is ommitted all country codes
+ *   will be returned.
+ * @return
+ *   If no country code is provided an array keyed by country code, values are
+ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+ *   FALSE will be returned. If the country code is valid the country code for
+ *   that country will be returned.
+ */
+function cck_phone_countrycodes($cc = NULL) {
+  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+  static $country_code = array(
+    'af' => 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 @@
+<?php
+// $Id: API.php,v 1.3 2010/07/12 09:54:52 ckng Exp $
+
+/**
+ * @file
+ * Phone Number custom country API
+ *
+ * 'CC' will be used throughout this document to indicate country code
+ * abbreviation. You should replace it with the correct country code
+ * in the following functions name. For full list of country code
+ * abbreviation, refer to the 2 alphabet list in the countries.txt.
+ */
+
+
+/**
+ * Validate country level phone number.
+ *
+ * @param $number
+ *   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
+ *   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 this country, FALSE otherwise.
+ */
+function CC_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+  // Assign $subaddress_error as FALSE if $subaddress is not valid
+  if (!empty($subaddress) && $subaddress_error) {
+    $error = t('%subaddress is not a valid extension number', array('%subaddress' => $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 @@
+<?php
+// $Id: cck_phone_countrycodes.inc,v 1.1 2010/07/08 11:20:27 ckng Exp $
+
+/**
+ * @file
+ * Defines country codes for Phone Number.
+ * Provide country name and international codes per country codes.
+ */
+
+/**
+ * Get all the country codes for supported countries.
+ *
+ * @param $cc
+ *   Optional, two character country code. If this is ommitted all country codes
+ *   will be returned.
+ * @return
+ *   If no country code is provided an array keyed by country code, values are
+ *   arrays with a 'country' and 'code' values. If an invalid $cc is provided,
+ *   FALSE will be returned. If the country code is valid the country code for
+ *   that country will be returned.
+ */
+function cck_phone_countrycodes($cc = NULL) {
+  // Alpha-2 codes from ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1
+  // Country codes from http://en.wikipedia.org/wiki/Country_calling_code
+  static $country_code = array(
+    'af' => 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 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Phone number field for Philippine phone numbers.
+ */
+
+/**
+ * Validate country level phone number.
+ *
+ * @param $number
+ *   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
+ *   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 this country, FALSE otherwise.
+ */
+function ph_validate_number($number = '', $subaddress = '', &$error, $phone_type = 'Voice') {
+  ph_sanitize_number($number);
+  if (!empty($number) && (drupal_strlen($number) < 8 || drupal_strlen($number) > 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 = $('<span class="default-cc"></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 = '<div class="form-item">'
+           + '  <label>' + Drupal.t('Filter') + ':</label> '
+           + '  <input class="cck-phone-filter" type="text" size="16" />'
+           + '</div>'
+           + '<div class="form-item">'
+           + '  <a class="cck-phone-check" href="javascript://">' + Drupal.t('Select all') + '</a>'
+           + '</div>';
+  $('.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,33 @@
+<?php
+// $Id$
+/**
+ * @file phone-field-view.tpl.php
+ * Default theme implementation for rendering phone number field.
+ *
+ * Available variables:
+ * - $phone: An associative array containing:
+ * -- value: Formatted phone number.
+ * -- int_code: International country calling code.
+ * -- tel_value: Formatted phone number for tel URI.
+ * -- subaddress_type: Subaddress value for telephone/fax's extension number (ext), 
+ *      ISDN subaddress (isub), fax's T33 subaddress (tsub), modem's parameters (type) 
+ *      and recommended parameters (rec). Ref: http://tools.ietf.org/html/rfc2806.
+ * -- subaddress_value: Subaddress value.
+ * -- type: hCard microformat property indicating the nature of the phone.
+ * -- value_attr: Attributes of value item.
+ * -- type_attr: Attributes of type item.
+ * -- extra: Annotation or extra phone number's description.
+ *
+ * @ingroup themeable
+ */
+?>
+<span class="tel">
+  <span <?php print drupal_attributes($phone['type_attr']); ?>><?php print $phone['type']; ?></span>
+  <a href="tel:<?php print $phone['tel_value']; ?><?php print empty($phone['subaddress_value']) ? '' : ';' . $phone['subaddress_type'] . ':' . $phone['subaddress_value']; ?>" <?php print drupal_attributes($phone['value_attr']); ?>>
+    <?php print '+' . $phone['int_code'] . ' ' . $phone['value']; ?>
+    <?php print empty($phone['subaddress_value']) ? '' : ' ' . $phone['subaddress_type'] . '. ' . $phone['subaddress_value']; ?>
+  </a>
+  <?php if ($phone['extra']): ?>
+  <span><?php print $phone['extra']; ?></span>
+  <?php endif; ?>
+</span>


