I'm try to programatically create a node that has some flexifield content. For normal CCK content, I do something like:

  $node = new stdClass();
  $node->type = 'custom';
  $node->status = 1;
  $node->title = 'foo';
  $node->field_bar[0]['value'] = 'test value';
  $node = node_submit($node);
  node_save($node);

This populates the type, status, title, and a custom 'bar' field.

I was hoping to populate a flexifield I might be able to do something like:

  $node = new stdClass();
  $node->type = 'custom';
  $node->status = 1;
  $node->title = 'foo';
  $node->field_flexisample[0]['value']['field_one'][0]['value'] = 'test value one';
  $node->field_flexisample[0]['value']['field_two'][0]['value'] = 'test value two';
  $node = node_submit($node);
  node_save($node);

This doesn't work.

What is the correct way to programmatically create a node w/ a flexifield?

Comments

bassam’s picture

Same here. I'm using flexifield with node reference.

I use the following code:


		$node->field_age_interval[0]['type'] = "flexi_age_intervals"; // content type name
		$node->field_age_interval[0]['value']['field_flexi_field_age_interval'][0]['nid'] = 131; // value
		$node->field_age_interval[0]["_weight"] = 0;

Any suggestions?

jeremy’s picture

I ended up upgrading to CCK 3 to solve my problem, utilizing multigroup to do what I needed to do. It then proved simple to programatically create nodes.

bassam’s picture

Interesting. I'll give it a try.

Thanks alot.

andrewspringman’s picture

Jeremy,

Based on your suggestion, I looked into CCK 3 and Multigroup. However, it appears that CCK 3 Multigroup has the same problem of adding empty items that Flexifield has.

Please see my entry concerning empty items in Flexifield: http://drupal.org/node/442834#comment-2246818

Also, the open issue concerning empty fields in CCK 3 Multigroup is here: http://drupal.org/node/522564

"What do empty items have to do with programmatically adding nodes with Flexifield?" you ask.

It's related only by my coding investment. I'm achieving everything I want with Flexifield except two things:

1) Getting rid of the empties
2) Automatically filling in my "Key" field with information in the node pointed to by the "Song" node reference.

The node_save method above looks like a great way to do the update for #2, but, as you say, that doesn't work. So, I'm looking for a way to code a solution with Flexifield.

I really wouldn't mind that much for the moment doing the MySQL table manipulation directly (I know, I know, but I'm desperate to get this working quickly). However, I have to admit I'm a bit lost. As you can see in my post (the one I referenced above), there are at least three tables involved and I still can't delete a Flexifield item. In general, I've rapidly gone from a Drupal user, to themer, to coder and my understanding is like Swiss cheese. (No offense to the Swiss, of course). I'm familiar with LAMP in general, just not the inner workings of Drupal and particularly not CCK and Flexifield. So, any help you or anyone else could give me would be awesome...even pointing me to documentation and saying "RTFM"...because I've been looking for the right M.

Blessings,
Andrew

andrewspringman’s picture

Let the truth be told. node_save does not work to change info as in #2 above (or add it as in your case). However, it DOES work to delete whole Flexifield items. See http://drupal.org/node/442834#comment-2253380

Since that works, I'm thinking there must be a way to tell the API that fields have changed (mark them as dirty?) or are new when you call node_save. I'm pretty sure I saw a code snippet once that marked the whole node as new before the call to node_save. That would help in your situation, but not in mine. Can anyone out there help?

jpklein’s picture

I was able to define flexifields programmatically by combining the code from reply #1 with functions from the latest version of the ORM project. Like:

<?php
// Create a new Article content-type node.
$drupalNodeTypeName = 'article';
$newNode = orm($drupalNodeTypeName)->create();

// Set the Title, Body, and Category.
$newNode->setTitle('Testing');
$newNode->body = 'This is the Body.';
$newNode->taxonomy[] = array('tid' => 10);

// Populate a cck field.
$newNode->field_byline[0]['value'] = 'This is a text field.';

// Create a flexifield entry with a node reference and cck field.
$newNode->field_gallery[0]['type'] = 'photoreference';  
// photoreference content type defined with the following two fields:
$newNode->field_gallery[0]['value']['field_photo'][0]['nid'] = 100;
$newNode->field_gallery[0]['value']['field_caption'][0]['value'] = 'This is the caption.';

// Save the node.
$newNode->save();
?>

(Drupal 6.14, Flexifield 6.x-1.0-alpha5, Orm 6.x-1.x-dev)

richardtmorgan’s picture

#6 worked great for me. I don't have the ORM module.

Just so long as I created the flexifield type first, I could then add the flexifield values:

$newNode->your_flexifield_name[0][type] = '{your_type_name}';
$newNode->your_flexifield_name[0][value][{field_name}][0][value]... etc...

etc... followed by a plain old:

node_save($newNode);

Seems to work for all flexifields. Thanks

hoppingmad’s picture

I had strange results trying to save a felxifield with several items using code from #6, when creating a new node. Saving the node with its basic information, then reloading and adding flexifield content, then saving the node again fixed the problem for me.

Thanks for pointing me in the right direction.