I've got a project where I need to copy field-collections from one node to a newly-created one. E.g. I have two different node types that both use the same field-collection type. I'm creating the second node type on the fly, and I need to copy any field collection items from the first to the second. Is there an easy way to do this, or do I need to create a new field collection item, copy the fields and then save it?

Comments

czigor’s picture

Status: Closed (fixed) » Active

I'm using this function to move a fc. Copying must be a lot trickier because you have to create a new fc for that, get all the properties of the old one etc.

$node = node_load( $nid);
//$field_fc_value is the id of the field collection item in the 'field_collection_item' table
$fc = field_collection_item_load($field_fc_value); 
move_field_collection_item($fc, 'node', $node);
node_save($node);

/*
 * Move the field collection item to a new entity. Assumes it is possible, so this is not fool safe.
 *
 * @param $fc
 *   The field collection item object to move to another entity.
 * @param $entity_type
 *   The entity type to move the field collection to.
 * @param $new_entity
 *   The entity object to move the field collection item to.
 */
function move_field_collection_item($fc, $entity_type, $new_entity) {
  if ($fc->item_id && $entity = $fc->hostEntity()) {
    foreach ($entity->{$fc->field_name} as $lang => &$data) {
      foreach ($data as $delta => $item) {
        if ($item['value'] == $fc->item_id) {
          // Delete the reference of the old entity.
          unset($data[$delta]);
          // Create the reference to the new entity.
          $new_entity->{$fc->field_name}[$lang][]['value'] = $fc->item_id;
        }
      }
    }
    entity_save($fc->hostEntityType(), $entity);
  }
}
ben coleman’s picture

Status: Active » Closed (fixed)
soncco’s picture

Where should I copy that code?

drupalok’s picture

sorry to reopen this, but i think there is need for more documentation (at least for me...)

could you provide a step by step?

ben coleman’s picture

Issue summary: View changes
Status: Active » Closed (fixed)
Tamuren’s picture

Status: Closed (fixed) » Active

Please instruct where to insert this code. Thanks.

jmuzz’s picture

The latest versions of field collection include support for cloning nodes via the node clone module so give that a try.

It may not be possible to make the code supplied 4 years ago work, as the module includes checks to prevent the host of a field collection item from being changed.

jmuzz’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

napche’s picture

Same issue, alternative solution :

  public function copyFieldCollection($source_entity, $target_entity, $fieldname) {
    $source_collection = $source_entity->{$fieldname}->getValue();
    $target_collection = $target_entity->{$fieldname}->getValue();
    if (empty($target_collection) && !empty($source_collection)) {
      foreach($source_collection as $collection_item) {
        $target_collection = $collection_item['field_collection_item']->createDuplicate();
        $target_collection->setHostEntity($target_entity);
      }
      $target_entity->save();
    }
  }
aaronelborg’s picture

Napche, that looks like it'd only work for D8.

napche’s picture

Correct.. my bad.