Aron Novak started this thread

$node->data1 = "foo";
$node->data2 = "bar";
node_object_prepare($node); // this is about the default values
node_save($node);

But I got a report that this is not a good way to do: http://drupal.org/node/196273
Summary: "node_object_prepare() and node_prepare() functions are meant to simulate the demonstration of a node"
And some users, who use FeedAPI + 3rd party modules together, really experience bugs around node creation / handling: http://drupal.org/node/195105 (summary: the core forum module uses form_alter to pass taxonomy-like data. And this data is lost now.)

Can you suggest me a perfect way to handle this problem? mustafau (http://drupal.org/user/207559) suggested to use drupal_execute($form_id, $form_values), but in this case, i had another problem: drupal_execute has no useful return value and $node structure remains unaltered, so i had to do a node_load after this, which is quite expensive.

Moshe Weitzman

In drupal5, you should call hook_node_submit() and hook_nodeapi('submit') before node_save(). that will assure that any group info gets saved (for example).

Larry Carfield

Using drupal_execute() or drupal_execute_macro() is a nasty, evil, slow, and ugly way to programmatically create users and nodes. It's also usually the only way that will reliably work. :-) I have, however, run into cases where it does not. For those, I have to fall back to creating the $node object myself and saving it. Fortunately I've only had to do that for one-off imports, so I could hard-code defaults.

Ashraf Amayreh

(INSERT)

$node = new stdClass();
$node->title = "{$XML->name}";
$node->body = "{$XML->description}";
$node->eid = $eid;
node_save($node);
module_invoke_all('nodeapi', $node, 'insert', NULL, NULL);

--------------
(UPDATE)

$node = node_load(array('nid' => 5));
$node->title = "{$XML->name}";
$node->body = "{$XML->description}";
$node->eid = $eid;

node_save($node);
module_invoke_all('nodeapi', $node, 'update', NULL, NULL);

Steve Ringwood

In drupal 4.7 and 5.x I have found that

$node = node_submit($node);
node_save($node);

generally works.

So how do we do it right in drupal 5? This is how node_factory module does it.

function node_factory_save_node( $edit, $succes_message= TRUE){
  // save proces
  $new_node = node_submit( $edit);
  node_save($new_node);
  if ($new_node->nid) {
    if( $succes_message){
      drupal_set_message( t('Automatic produced %node_type with title %title', array( '%node_type' => $new_node->type, '%title' => $new_node->title)));
    }
    return $new_node->nid;
  } else {
    drupal_set_message( t('Cannot create %new_node', array( '%new_node'=> $new_node->type)), 'error');
    return FALSE;
  }
}

Most of the others use an object ... node factory uses an array :-/

Comments

sime’s picture

I think you should incorporate Moshe' suggestion.

clemens.tolboom’s picture

Moshe suggest using hook_node_submit() and hook_nodeapi('submit') before node_save()

This would result for node_factory

  $new_node = node_submit( $edit);

// extra lines
  module_invoke_all('submit', $new_node);
  module_invoke_all('nodeapi', $new_node, 'submit', NULL, NULL);
// end extra lines

  node_save($new_node);
  if ($new_node->nid) {

Will that work?
I must figure out a test scenario. Comprising ie og and image_composition.

lukas.fischer’s picture

I think the main problem with cck is, that we don't have a propel "model". I'm used to develop clean "models" which handles the data. Controllers access the models to change the date. In Drupal the controller and model are done with forms and cck in a somehow complicated way.

My needs for a CCK API:
- object oriented access
- $node = new CCKType(); The CCKType Class is a inheritance of an abstract CCK class
- $node->save (create, update)
- $node->fetch(nid)
- $node->fetchAll(where statement)

How to do?
I don't know. Probably a new module which is completely new but uses the same datastructure/tables as the old cck modules. If you would like to use, the new method you also need to rewrite the forms or at least create new methods for forms like $form->getValues() where you can pass the variables to the nodeapi.

Why I think this is good?
- Again, to have a clean model.
- to avoid programming boring sql statements (we also have already meta information for the db structure)
- the model is extensible so you still can write your own sql if you like

clemens.tolboom’s picture

node_submit is already calling hook_nodeapi( 'submit',...)

function node_submit()
...
node_invoke($node, 'submit');
node_invoke_nodeapi($node, 'submit');

So I'm not sure #2 makes sense.

Summit’s picture

Subscribing,
very much interested in getting nodes programmically through using a node-template with in the node-body fields like vocab1-taxonomy/term1 vocab2-taxonomy/term2 etc..
And then using taxonomy_import/export for getting a sourcefile, or may be direct throuhg drupal-taxonomy and then getting as many nodes with different node-body filling as there are taxonomy terms.

greetings,
Martijn

clemens.tolboom’s picture

Status: Active » Closed (won't fix)