0

CONTEXT

Adding a node with its field-collection field and inner fields programmatically. Saving the node. Then trying to reach the inner fields - bam! - they are not in the array!

MORE INFO

if I am adding the node manually (not by code) and then trying to get to the inner fields - they ARE there.

[Edit] - The same problem of undefined inner field happens if saving using VBO (Views Bulk Operations module). So, can it be that the structure is bad? However, I have built the collection field using the manual interface only, not by code.

CREATING A NODE WITH FIELD COLLECTION

$node = // Creating a node
$fc_item = entity_create('field_collection_item', array('field_name' => $field_machine_name));
$fc_item->{$field_machine_name}[$node->language][$index][$value_column_name] = $field_value;
$fc_item->setHostEntity('node', $node, $node->language);
$fc_item->save(TRUE);
$node = node_submit($node);
node_save($node);

TRYING TO GET INSIDE FIELD COLLECTION JUST MADE

$value = $node->field_coll_print_authors['und'][0];
print_r($value);

I get:

Array
(
    [value] => 278 // This is the field collection item id
    [revision_id] => 1533
)

However, what I would have expect, and what I actually DO HAVE when adding a node of the same type by hand is:

Array
( 
    [field_print_author_last_name] => Array 
    (
        [und] => Array 
        (
            [0] => Array 
            (
                [value] => amir // This is the value I need
            ) 
        ) 
    )

HELP

Well, is there any function I have not called in order to attach the field collection item properly to the node? Or something else is missing?

Thanks for your help!

  • Thanks for commenters below - I will get to it in the coming phase of this project and will update here. – Amir Simantov Jan 21 '15 at 19:23
  • Hi guys. I have managed to get to the values of the inner fields and change them inside the session; that is, I can see the new value with dpm() function. However, the new value is not saved to the database... – Amir Simantov Mar 20 '15 at 12:26
0

You have to load the field collection entity. You could use:

$field_colection = entity_load('field_collection_item', array($node->field_coll_print_authors['und'][0]['value']));

print_r($field_collection);

the $field_collection object will contain all data you need ;)

1

Field collections are not stored in full with the Loaded node access via node_load(); only their entity ID.

The data does sometimes look like that, for example in a node form (because it actually has to create fields for them) and in a rendered node via node_view()(depending how you have set it in the view mode settings).

But you can load them easy enough and get the values that way.

Here is an example :

Dynamically creating a node with multiple field collections :

  global $user;
  $type = 'floor_staff_checklist';
  $event_id        = 12345;

  $chk_node        = new stdClass();
  $chk_node->type  = $type;
  $chk_node->title = '';
  node_object_prepare($chk_node);
  $chk_node->uid                           = $user->uid;
  $chk_node->nid                           = 0;
  $chk_node->status                        = 1;
  $chk_node->promote                       = 0;
  $chk_node->field_event[LANGUAGE_NONE][0] = array(
    'target_id'   => $event_id,
    'target_type' => 'node',
  );

  if ($type == 'floor_staff_checklist') {
    $time = strtotime("01-01-2000 19:30:00");
    for ($i = 0; $i < 22; $i++) {
      $strtime = date("H:i", $time);
      $time += 1800;
      $flrchhk_fc = entity_create('field_collection_item', array('field_name' => 'field_floor_check'));
      $flrchhk_fc->setHostEntity('node', $chk_node);
      $flrchhk_fc->field_check_time[LANGUAGE_NONE][0]['value'] = $strtime;
      $flrchhk_fc->save();
    }
  }

  $chk_node = node_submit($chk_node);
  node_save($chk_node);
  drupal_goto("node/$chk_node->nid");
}

In this situation, I am creating a node, and creating 24 field collections within it, one for every hour, then saving the node.

And if you want to view the data :

$entity = entity_load_single($chk_node->nid);
if (isset($entity->field_floor_check[LANGUAGE_NONE]) && !empty($entity->field_floor_check[LANGUAGE_NONE])) {
  $fcs = array_column($entity->field_floor_check[LANGUAGE_NONE], 'value');
  $items = entity_load('field_collection_item', $fcs);
  foreach ($items as $item) {
    dpm($item);
  }
}

This will load the node, access its references to the field collections, load them, and loop through them printing the contents through Krumo (Devel module).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.