34

How can I programmatically create nodes with date and image fields?

I know I can do it in Drupal 7 with the following code.

global $user;

  $node = new stdClass();
  $node->title = "YOUR TITLE";
  $node->type = "YOUR_NODE_TYPE";
  node_object_prepare($node); // Sets some defaults. Invokes hook_prepare() and hook_node_prepare().
  $node->language = LANGUAGE_NONE; // Or e.g. 'en' if locale is enabled
  $node->uid = $user->uid; 
  $node->status = 1; //(1 or 0): published or not
  $node->promote = 0; //(1 or 0): promoted to front page
  //image field
  $existing_filepath = "/home/nzcodarnoc/sites/default/files/imported/picture.jpg"
  $new_filepath = "public://picture.jpg"
  // Create the file object
  $drupal_file = file_save_data(file_get_contents($existing_filepath), $new_filepath);
  $drupal_file->alt = $node->title;
  $drupal_file->title = $node->title;
  // Assign the file object to the node, as an array
  $node->field_my_file[$node->language][0] = get_object_vars($drupal_file);
  //date field
  $node->birth_date[LANGUAGE_NONE][0]['value'] = time();  
  $node = node_submit($node); // Prepare node for saving
  node_save($node);

What is the equivalent code for Drupal 8?

56

The following code will help you to save an image in a new node.

use \Drupal\node\Entity\Node;
use \Drupal\file\Entity\File;

// Create file object from remote URL.
$data = file_get_contents('https://www.drupal.org/files/druplicon.small_.png');
$file = file_save_data($data, 'public://druplicon.png', FILE_EXISTS_REPLACE);

// Create node object with attached file.
$node = Node::create([
  'type'        => 'article',
  'title'       => 'Druplicon test',
  'field_image' => [
    'target_id' => $file->id(),
    'alt' => 'Hello world',
    'title' => 'Goodbye world'
  ],
]);
$node->save();

For more information, see http://realityloop.com/blog/2015/10/08/programmatically-attach-files-node-drupal-8.

  • In this specific example, we don't need \Drupal\file\Entity\File as we are directly getting the image file from Internet. But if you see this link realityloop.com/blog/2015/10/08/…, there you will find examples of File entity being used, // Create file object from a locally copied file. $uri = file_unmanaged_copy('public://source.jpg', 'public://destination.jpg', FILE_EXISTS_REPLACE); $file = File::Create([ 'uri' => $uri, ]); $file->save(); – amitgoyal Aug 12 '16 at 5:09
  • The example image doesn't exist. This one does: drupal.org/files/druplicon-small.png – Kari Kääriäinen Jun 1 '17 at 4:22
13

In drupal 8 entities are objects and as such, to create an entity is to create an instance of the entity's type class. If you know the class of the entity then you can either use the new keyword or the create function.

I.E. $foo = new Foo(); or $foo = Foo::create();

If you don't know the class of entity (only the machine name) then you can use the request the Storage class like so: \Drupal::entityTypeManager()->getStorage($entity_type_id)->create();

To populate the fields of an entity you can either use the $entity->set($key, $value) method on the entity object or pass a key=>value array to the entity constructor. As such:

$foo = new Foo([
  'name'=>'bar',
  'baz'=> TRUE,
  'multi_value' => [
    'first',
    'second',
    'third',
  ]
]);

To save an entity you only have to call the $entity->save() method on the entity object.

Since files in drupal 8 are also entities you need to either pass the id of the file entity, or the actual file entity, as the value.

$file_1 = File::load(1);
$foo->set('bar_files', [
  $file_1,
  2
]);

Here is a code for your specific scenario:

$node_entity_type = \Drupal::entityTypeManager()->getDefinition('node');
// The [file_save_upload][1] function returns an array of all the files that were saved.
$poster_images = file_save_upload($upload_name, $validators, $destination);
$node = new Node([
  $node_entity_type->getKey('bundle') => 'movie',
  $node_entity_type->getKey('label') => 'Foo',
  'field_release_date' => '1/1/2015',
  'field_poster_image' => $poster_images,
]);
$node->save();
  • I want to add one image field and one date ffield,provide your answer with this field types. – Yusef Mohamadi Jan 3 '16 at 5:37
  • But how to populate text fields programmatically in Drupal 8, at the time of node creation? – W.M. Jan 9 '16 at 17:32
  • The data in $node_data is mapped directly to the node fields. If you want to add text to a field called field_body just add another entry with the key field_body. – Eyal Jan 13 '16 at 11:25
  • I've updated my answer with more details. You are welcome. – Eyal Jan 15 '16 at 15:37
  • 1
    Updated my answer – Eyal Mar 17 '17 at 13:35
12

I think that object oriented way is more convenient, isn't it?

use Drupal\node\Entity\Node;

$my_article = Node::create(['type' => 'article']);
$my_article->set('title', 'My article');
$my_article->set('field_text', 'My text');
$my_article->set('field_image', FID);
$my_article->set('field_user', UID);
$my_article->enforceIsNew();
$my_article->save();
7

If you want to do it in the most clean way (testable), use entity_type.manager service:

$storage = $this->entityTypeManager->getStorage($entity_type_id);
$my_entity = $storage->create([
   ....
]);

The problem with Node::create function, that it is static call, and that's why you cannot really unit test your class anymore. Avoid doing static calls whenever it's possible. It will make your code more readable (because dependencies will be clear).

2

Following code is working for me

use \Drupal\node\Entity\Node;
use \Drupal\file\Entity\File;

$node = entity_create('node', array(
'type' => 'article',
'title' => $form_state->getValue('title'),
'body' => array(
'value' => $form_state->getValue('body'),
'format' => 'basic_html',
),
'uid' => $uid,
));
$node->save();
  • 1
    entity_create is deprecated – Eyal Feb 21 '16 at 8:17
  • Also, $form_state is available only in specific contexts; otherwise, you cannot access it. – kiamlaluno Feb 28 '16 at 12:33
2

Another way to create node with image is:

use \Drupal\file\Entity\File;

// Create file object from remote URL.
$data = file_get_contents('https://www.drupal.org/files/druplicon.small_.png');
$file = file_save_data($data, 'public://druplicon.png', FILE_EXISTS_REPLACE);

$node = \Drupal::entityTypeManager()->getStorage('node')->create(array(
  'type'        => 'article',
  'title'       => 'Druplicon test',
  'field_image' => [
    'target_id' => $file->id(),
    'alt' => 'Hello world',
    'title' => 'Goodbye world'
  ],
));
$node->save();
0
use Drupal\Core\Language\Language;


$definition = \Drupal::entityTypeManager()->getDefinition('node');
$values = [
    $definition->getKey('bundle') => 'basic_page',
    'langcode'                    => Language::LANGCODE_NOT_SPECIFIED,
    'title'                       => '...',
];
$entity = \Drupal::entityTypeManager()->getStorage('node')->create($values);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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