Programmatically setting an image field from hook_node_insert (drupal 7) 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-&gt;field_screenshot[LANGUAGE_NONE]['0']['fid'] = $file-&gt;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?
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-&gt;field_screenshot[LANGUAGE_NONE]['0']['fid'] = $file-&gt;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-&gt;nid will probably suffice). Otherwise you'll end up doing this operation every time the new node is subsequently saved.