You are here

function drush_multifield_convert_field_collection in Multifield 7

Same name and namespace in other branches
  1. 7.2 multifield.drush.inc \drush_multifield_convert_field_collection()
1 string reference to 'drush_multifield_convert_field_collection'
multifield_drush_command in ./multifield.drush.inc
@file Drush integration for the Multifield module.

File

./multifield.drush.inc, line 25
Drush integration for the Multifield module.

Code

function drush_multifield_convert_field_collection($source_field_name) {
  $source_field = field_read_field($source_field_name);
  $target_field_name = drush_get_option('target-field-name', $source_field_name);
  if (empty($source_field)) {
    return drush_set_error('FIELD_NOT_FOUND', "Field {$source_field_name} not found.");
  }
  elseif ($source_field['type'] != 'field_collection') {
    return drush_set_error('FIELD_NOT_FIELD_COLLECTION', "Field {$source_field_name} is not a field_collection field type.");
  }
  elseif ($source_field['storage']['type'] != 'field_sql_storage') {
    return drush_set_error('FIELD_STORAGE_NOT_SQL', "Field {$source_field_name} cannot be converted unless it uses field_sql_storage storage.");
  }
  elseif ($source_field_name != $target_field_name && field_read_field($target_field_name)) {
    return drush_set_error('FIELD_ALREADY_EXISTS', "The target field {$target_field_name} already exists.");
  }
  $data_table = _field_sql_storage_tablename($source_field);
  $revision_table = _field_sql_storage_revision_tablename($source_field);
  $data_count = db_select($data_table)
    ->countQuery()
    ->execute()
    ->fetchField();
  $revision_count = db_select($revision_table)
    ->countQuery()
    ->execute()
    ->fetchField();
  if (!drush_confirm(dt("You are about to convert {$source_field_name} field collection to a {$target_field_name} multifield. {$data_count} entity data records and {$revision_count} entity revision records will also be converted. Are you sure?"))) {
    return FALSE;
  }

  // Double check that the field instances
  $subfields = array();
  $subinstances = field_read_instances(array(
    'entity_type' => 'field_collection_item',
    'bundle' => $source_field_name,
  ));
  foreach ($subinstances as $subinstance) {
    $subfield = $subfields[$subinstance['field_name']] = field_read_field($subinstance['field_name']);
    if ($subfield['cardinality'] != 1) {
      return drush_set_error('FIELD_NOT_FOUND', "Field {$source_field_name} cannot be converted since subfield {$subinstance['field_name']} has cardinality of {$subfield['cardinality']} when it should be 1.");
    }
  }
  $instances = field_read_instances(array(
    'field_name' => $source_field_name,
  ));
  $settings = field_bundle_settings('field_collection_item', $source_field_name);

  // Disable the field value purging until our operation is finished.
  $old_batch_size = variable_get('field_purge_batch_size', 10);
  variable_set('field_purge_batch_size', 0);
  field_delete_field($source_field_name);
  $source_field['deleted'] = 1;

  // Re-create the field as a multifield.
  $target_field = array_intersect_key($source_field, array_flip(array(
    'settings',
    'cardinality',
    'locked',
  )));
  $target_field['storage'] = array_intersect_key($source_field['storage'], array_flip(array(
    'type',
    'settings',
  )));
  $target_field['type'] = 'multifield';
  $target_field['field_name'] = $target_field_name;
  field_create_field($target_field);

  // Re-create the subinstances.
  foreach ($subinstances as $subinstance) {

    // If the subfield happened to get deleted, recreate it.
    if (!field_read_field($subinstance['field_name'])) {
      $subfield = $subfields[$subinstance['field_name']];
      field_create_field($subfield);
      $subfields[$subinstance['field_name']]['deleted'] = 1;
    }
    $subinstance['entity_type'] = 'multifield';
    $subinstance['bundle'] = $target_field_name;
    field_create_instance($subinstance);
  }

  // Re-read the field now that the subfields were recreated.
  $target_field = field_read_field($target_field_name);

  // Re-create the instances.
  foreach ($instances as $instance) {
    if ($instance['widget']['type'] == 'field_collection_embed') {
      $instance['widget']['type'] = 'multifield_default';
      $instance['widget']['module'] = 'multifield';
    }
    foreach ($instance['display'] as $view_mode => $display) {
      if ($display['type'] == 'field_collection_view') {
        $instance['display'][$view_mode]['type'] = 'multifield_default';
        $instance['display'][$view_mode]['module'] = 'multifield';
      }
    }
    $instance['field_name'] = $target_field_name;
    field_create_instance($instance);
  }
  field_bundle_settings('multifield', $target_field_name, $settings);
  $batch = array();
  if ($data_count) {
    $batch['operations'][] = array(
      'drush_multifield_convert_field_collection_table',
      array(
        $source_field,
        $target_field,
        $subfields,
        'data',
      ),
    );
  }
  if ($revision_count) {
    $batch['operations'][] = array(
      'drush_multifield_convert_field_collection_table',
      array(
        $source_field,
        $target_field,
        $subfields,
        'revision',
      ),
    );
  }
  if (!empty($batch)) {
    batch_set($batch);
    drush_backend_batch_process();
  }
  variable_set('field_purge_batch_size', $old_batch_size);
}