There are many situations where programmatically creating a node is necessary. I'm sure we've all used this method at least once and each time may call for a slightly different configuration. Recently, I wrote a script to migrate a fairly small number of nodes (around 150). Along with the standard title, body, status and fields, I also had to migrate terms and attachments. Terms are fairly easy, but I've never needed to migrate attachments until now. I found a site which was very helpful with programmatically including attachments to a node. This is not to attach file to a file field, but to attach files as an attachment which uses the core Upload module. The main chunk of code is below:
foreach ($files as $file) { $file_obj = new stdClass(); $file_obj->filename = $file->filename; $file_obj->filepath = $file->filepath; $file_obj->filemime = $file->filemime; $file_obj->filesize = $file->filesize; $file_obj->filesource = $file->filename; // You can change this to the UID you want $file_obj->uid = $file->uid; $file_obj->status = $file->status; $file_obj->timestamp = $file->timestamp; $file_obj->list = 1; $file_obj->new = true; // Save file to files table drupal_write_record('files', $file_obj); // Attach the file object to your node $node->files[$file_obj->fid] = $file_obj; }
First thing we need to do is create a new file object. Fill in the file name, path, mime, size and source variables. In my case, I had these variables available from the old database, so I needed to save the new object into the new files table to get a file ID. These variables can also be retrieved by file_save_upload if you're uploading a new file. Afterwards, each file ID needs to be set as an array in the node object. Then node_save to commit the changes. Saved attachments are written into the upload table where they can reference the file ID and node ID.