Seeing that there are still quite a number of deployed phone.module, it will be good to have a migration option from D5 & D6 of phone.module. However the data migration might be a problem as the phone number is captured entirely including country codes and extension, whereas in cck_phone these are separated pieces. Would like to see proposal on how this can be done.

Comments

will_in_wi’s picture

Subscribe

scottrigby’s picture

Status: Active » Needs review

@ckng Maybe something like this pseudocode below?

I didn't add configurations – I can image different options for handling the move from phone to cck_phone:

  • Replace all old phone fields with cck_phone fields of the exact same name? (this seems useful for updating existing features that already store the old phone fields in code for example. A drush fu would update the content.inc without needing to change the info file declarations)
  • Same as above (replace phone fields with cck_phone equivalents), but only on specified phone fields?
  • Same as above (specify which phone fields to migrate), but instead specify new or existing cck_phone field names to map the old ones to?

Ideally it'd be good to keep it simple. I'm kind of leaning toward favoring replacing all old phone fields with new cck_phone fields of the same name – as a configuration, so site admins can take or leave the migration option… What do you think?

function cck_phone_update_N() {
  $ret = array();
  
  // Example field names.
  // @todo base this on some configurations.
  // @todo probably loop through all content_fields(). This is just an example below.
  $phone_field_name = 'field_phone';
  $cck_phone_field_name = 'field_cck_phone';
  
  // Get field data. 
  drupal_get_schema(NULL, TRUE);
  $phone_field = content_fields($phone_field_name);
  
  // Assumes you've made a new field already and both fields are in the same table.
  // @todo genericize this, or automate the new cck_phone field creation.
  $dbinfo = content_database_info($phone_field);
  $sql = "select * from {{$dbinfo['table']}}";
  $result = db_query($sql);
  while ($row = db_fetch_object($result)) {
    // The phone module column we care about is FIELD_NAME_value.
    // cck_phone module stores 3 columns: FIELD_NAME_number, FIELD_NAME_country_codes and FIELD_NAME_extension.
    // Remove clean non-numeric characters, and strip the country code from the front.
    $country_code = $phone_field['phone_country_code'];
    $old_number = $row->{"{$phone_field_name}_value"};
    $new_number = preg_replace("/\D*|^$country_code/", '', $old_number);
    $row->{"{$cck_phone_field_name}_number"} = $new_number;
    // @todo parse country id-code from numeric $phone_field['phone_country_code'].
    // Set 'us' as an example for now.
    $row->{"{$cck_phone_field_name}_country_codes"} = 'us';
    // The phone module doesn't have extension support. 
    $row->{"{$cck_phone_field_name}_extension"} = NULL;
    drupal_write_record($dbinfo['table'], $row, array('nid', 'vid'));
  }

  // Delete the old phone field.
  module_load_include('inc', 'content', 'includes/content.crud');
  content_field_instance_delete($phone_field_name, $phone_field['type_name'], FALSE);
  
  // If we do this in hook_update_N(), give a friendly message that we're done.
  $ret[] = array(
    'success' => TRUE,
    'query' => t('The phone field %phone_field has been replaced with the cck_phone field %cck_phone_field.', array('%phone_field' => $phone_field_name, '%cck_phone_field' => $cck_phone_field_name)),
  );

  // Manually clear this if we pass FALSE to content_field_instance_delete().
  cache_clear_all();

  return $ret;
}
ckng’s picture

Version: 6.x-1.0-beta1 » 6.x-1.x-dev
Status: Needs review » Needs work

Yes, we should keep it simple.
I would imagine a link or menu item to let user migrate all old phone fields with new cck_phone fields of the same name.