You are here

function node_convert_field_convert in Node Convert 7

Same name and namespace in other branches
  1. 5 node_convert.module \node_convert_field_convert()
  2. 6 node_convert.module \node_convert_field_convert()

Transfers information from source_field to dest_field.

Parameters

$node: The node object to be converted.

$source_field: A string containing the name of the source field which contains to be transferred information.

$destination_field: A string containing the name of the destination field where the information should be stored.

string $destination_node_type: A string containing the destination node type of the node.

array $node_revisions:

Return value

string Returns REPLACE_BODY if something replaced the body field, or was appended to it.

1 call to node_convert_field_convert()
node_convert_node_convert in ./node_convert.util.inc
Converts a node to another content type.

File

./node_convert.util.inc, line 118
API and Utility Functions.

Code

function node_convert_field_convert(&$node, $source_field, $destination_field, $destination_node_type = '', $node_revisions = array()) {
  $field_info_source = field_info_fields();

  // Get source field information
  $field_info_source = $field_info_source[$source_field];
  $db_info_source = $field_info_source['storage'];

  // Get DB specific source field information
  if ($destination_field == 'discard') {

    // Delete node info in the separate field table
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
    return NULL;
  }
  $field_info_destination = array();
  $db_info_destination = array();
  if (!in_array($destination_field, array(
    'discard',
    APPEND_TO_BODY,
    REPLACE_BODY,
  ))) {
    $field_info_destination = field_info_fields($destination_field);

    // Get destination field information
    $field_info_destination = $field_info_destination[$destination_field];

    // Get destination field information
    $db_info_destination = $field_info_destination['storage'];

    // Get DB specific destination field information
  }

  // We save each field value from the DB for transfer. (this only applies to the current revision of the field)
  $source_values = field_get_items('node', $node, $source_field);
  if (count($node_revisions) > 1 && !in_array($destination_field, array(
    APPEND_TO_BODY,
    REPLACE_BODY,
  ))) {

    // Get all field revisions for current node
    $field_revision_values = array();
    $field_revision_source_table = current(array_keys($db_info_source['details']['sql']['FIELD_LOAD_REVISION']));
    $field_revision_destination_table = current(array_keys($db_info_destination['details']['sql']['FIELD_LOAD_REVISION']));
    $source_columns = array(
      'entity_type',
      'entity_id',
      'revision_id',
      'bundle',
      'delta',
      'language',
    );
    foreach ($field_info_source['columns'] as $column => $attributes) {
      $source_columns[] = _field_sql_storage_columnname($source_field, $column);
    }
    $revision_query = db_select($field_revision_source_table, 'r', array(
      'fetch' => PDO::FETCH_ASSOC,
    ))
      ->condition('entity_type', 'node')
      ->condition('bundle', $node->type)
      ->condition('entity_id', $node->nid)
      ->condition('revision_id', $node->vid, '<>')
      ->fields('r', $source_columns)
      ->execute();

    // Change the bundle to the destination type of the node
    foreach ($revision_query as $row) {
      $row['bundle'] = $destination_node_type;
      $field_revision_values[] = $row;
    }

    // Remove all field revisions for current field in DB
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);

    // Reinsert the field revisions in the destination field revision table
    $query = db_insert($field_revision_destination_table);
    $columns = array(
      'entity_type',
      'entity_id',
      'revision_id',
      'bundle',
      'delta',
      'language',
    );
    foreach ($field_info_destination['columns'] as $column => $attributes) {
      $columns[] = _field_sql_storage_columnname($destination_field, $column);
    }
    $query
      ->fields($columns);
    foreach ($field_revision_values as $row) {
      $query
        ->values(array_values($row));
    }
    $query
      ->execute();
  }
  else {

    // After getting the source field values, we delete the values stored in the DB (this deletes values for all field revisions)
    node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
  }

  // The source field value should be appended to the body or replaced.
  if ($destination_field == APPEND_TO_BODY || $destination_field == REPLACE_BODY) {
    static $node_body = '';

    //static $node_teaser = '';

    // We try to get the node body from a static variable, which means we did some body manipulations, otherwise load it.
    if (empty($node_body)) {
      $node_body_field = field_get_items('node', $node, 'body');
      $node_body = $node_body_field[0]['value'];

      //$node_teaser = $node_body_field[0]['summary'];
    }

    // Double check we have values in the field.
    if (is_array($source_values)) {

      // Get the field value.
      $field_value = node_convert_format_field_value($node, $field_info_source, TRUE);
      if ($destination_field == APPEND_TO_BODY) {
        $node_body = $node_body . "\n" . $field_value;

        //$node_teaser = $node_teaser . "\n" . $field_value['value'];
      }
      elseif ($destination_field == REPLACE_BODY) {
        $node_body = $field_value;

        //$node_teaser = $field_value['value'];
      }
      $lang_code = field_language('node', $node, $source_field);
      $node->body[$lang_code][0]['value'] = $node_body;

      //$node->body[$lang_code][0]['summary'] = $node_teaser;
    }
    return REPLACE_BODY;
  }

  // We put each field value back into the DB
  // To do it we first get the id of the field, then we find its language code from the source value
  // We add $source_values into the node object, and invoke field_storage write
  $field_ids = array(
    $field_info_destination['id'] => $field_info_destination['id'],
  );
  $lang_code = field_language('node', $node, $source_field);

  // Make sure that we actually have values in the source field
  if ($source_values !== FALSE) {
    $node->{$destination_field}[$lang_code] = $source_values;
  }
  else {
    $node->{$destination_field} = array();
  }

  // Give possibility to fields to pre-process their data
  // (e.g., Link module transforms attribute array into a serialized array before insertion)
  field_attach_presave('node', $node);

  // For some reason link_field_presave doesn't exist anymore, so we have to call it the processing function used inside manually.
  if ($field_info_destination['type'] == 'link_field') {
    $instances = field_info_instances('node', $destination_node_type);
    link_field_update('node', $node, $field_info_destination, $instances[$destination_field], $lang_code, $node->{$destination_field}[$lang_code]);
  }
  try {
    module_invoke($db_info_destination['module'], 'field_storage_write', 'node', $node, FIELD_STORAGE_INSERT, $field_ids);
  } catch (Exception $e) {
    drupal_set_message(t('Caught exception: @exception', array(
      '@exception' => $e
        ->getMessage(),
    )));
  }
  return NULL;
}