Realityloop: Programmatically attach files to a node in Drupal 8

8 Oct

Stuart Clark
If you're a Drupal developer, there's a good chance that at some point you've done a search for "Programmatically attach files to a node in Drupal 7" or similar. I know I've done the search repeatedly, as while it's a common enough task it involves just a bit too much code to not be retained by my long term memory.

Now that Drupal 8 is upon us adding a file to a node (or any entity) is far easier. I'm not going to do a comparison, however, as I don't want to confuse anyone who stumbles onto this post with the intent of simply copying and pasting the below code snippet, so you'll just have to take my word for it.
 

So, straight to the point, this is all it takes to programmatically attach a file to a file field on a Node:

  1. use \Drupal\node\Entity\Node;
  2.  
  3. // Create file object from remote URL.
  4. $data = file_get_contents('https://www.drupal.org/files/druplicon.small_.png');
  5. $file = file_save_data($data, 'public://druplicon.png', FILE_EXISTS_REPLACE);
  6.  
  7. // Create node object with attached file.
  8. $node = Node::create([
  9. 'type' => 'article',
  10. 'title' => 'Druplicon test',
  11. 'field_image' => [
  12. 'target_id' => $file->id(),
  13. ],
  14. ]);
  15. $node->save();

In the above example we are taking a remote file and saving it locally, which is probably the most commonly used case when programmatically adding a file to a node.

 

What if the file is already present in your local file system and you want to attach it to an existing node? Here's an example for that too:

  1. use \Drupal\node\Entity\Node;
  2. use \Drupal\file\Entity\File;
  3.  
  4. // Create file object from a locally copied file.
  5. $uri = file_unmanaged_copy('public://source.jpg', 'public://destination.jpg', FILE_EXISTS_REPLACE);
  6. $file = File::Create([
  7. 'uri' => $uri,
  8. ]);
  9. $file->save();
  10.  
  11. // Load existing node and attach file.
  12. $node = Node::load(1);
  13. $node->field_image->setValue([
  14. 'target_id' => $file->id(),
  15. ]);
  16. $node->save();

 

And lastly, what if you want to stick a placeholder file to a node? Thanks to Drupal 8, this is too easy:

  1. use \Drupal\node\Entity\Node;
  2.  
  3. $node = Node::create([
  4. 'type' => 'article',
  5. 'title' => 'Generated image test',
  6. ]);
  7. $node->field_image->generateSampleItems();
  8. $node->save();

 

So get to it, programmatically attach files to your nodes and be merry!drupaldrupal 8drupal planet