Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I have a content type that has a file field (which accepts only .zip file) and a screenshot which is an image field and is not displayed on the content submission form. Instead I have a module that unzips the .zip file from hook_node_insert. At this point I would also like to set the screenshot to be a .png extracted from the .zip file. So far I have had no success and I always seem to get an error like this:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '463' for key 'PRIMARY': INSERT INTO {node} (nid, vid, type, language, title, uid, status, created, changed, comment, promote, sticky, tnid, translate, uuid) VALUES (:db_insert_placeholder_0, 

Since I was having trouble getting this to work, I tried what I thought might be simpler, I.E. trying to set the node to some image from the web using code like this:

  $image = file_get_contents('http://drupal.org/files/druplicon.large_.png');
  $file  = file_save_data($image, 'public://drupalicon.png',FILE_EXISTS_REPLACE);
  $node->field_screenshot[LANGUAGE_NONE]['0']['fid'] = $file->fid;
  node_save($node);

but I always get the integrity constraint problem listed above. Could my problem be related to trying to do this from hook_node_insert?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

node_save() actually invokes hook_node_insert() so calling it from inside that hook probably isn't the best idea (I'm surprised you don't get out of memory errors doing that actually).

Instead you might want to use hook_node_presave(), which is called before the node and associated data is committed to the database:

function MYMODULE_node_presave($node) {
  $image = file_get_contents('http://drupal.org/files/druplicon.large_.png');
  $file  = file_save_data($image, 'public://drupalicon.png',FILE_EXISTS_REPLACE);
  $node->field_screenshot[LANGUAGE_NONE]['0']['fid'] = $file->fid;
}

That way you won't have to call node_save() so you won't get the error, and the field data will save with the node as normal.

As hook_node_presave() is called for both inserts and updates, you might want to add a condition in there to check whether the node is new or not (checking $node->nid will probably suffice). Otherwise you'll end up doing this operation every time the new node is subsequently saved.

share|improve this answer
    
Thanks you so much, I was stuck on that for awhile and thought it might have something to do with the hook I was calling it from. Also, checking if the fid is empty also seems to work to make this only happen the first time you save! –  Mike2012 Apr 25 '12 at 22:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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