48

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);
$node->language = LANGUAGE_NONE;
$node->uid = $user->uid; 
$node->status = 1; //(1 or 0): published or not
$node->promote = 0; //(1 or 0): promoted to front page

$existing_filepath = "/home/nzcodarnoc/sites/default/files/imported/picture.jpg";
$new_filepath = "public://picture.jpg";
$drupal_file = file_save_data(file_get_contents($existing_filepath), $new_filepath);
$drupal_file->alt = $node->title;
$drupal_file->title = $node->title;
$node->field_my_file[$node->language][0] = get_object_vars($drupal_file);
$node->birth_date[LANGUAGE_NONE][0]['value'] = time();  
$node = node_submit($node);
node_save($node);

What is the equivalent code for Drupal 8?

0

7 Answers 7

73

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();
0
17

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();
16

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();
6
  • I want to add one image field and one date ffield,provide your answer with this field types.
    – Yuseferi
    Commented Jan 3, 2016 at 5:37
  • But how to populate text fields programmatically in Drupal 8, at the time of node creation?
    – W.M.
    Commented Jan 9, 2016 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
    Commented Jan 13, 2016 at 11:25
  • I've updated my answer with more details. You are welcome.
    – Eyal
    Commented Jan 15, 2016 at 15:37
  • 1
    Updated my answer
    – Eyal
    Commented Mar 17, 2017 at 13:35
10

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).

6

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();
2
  • 1
    entity_create is deprecated
    – Eyal
    Commented Feb 21, 2016 at 8:17
  • Also, $form_state is available only in specific contexts; otherwise, you cannot access it.
    – avpaderno
    Commented Feb 28, 2016 at 12:33
5

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();
1
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 and acknowledge you have read our privacy policy.

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