1

Some years ago I made a Drupal 7 site. I want to remake the site with Drupal 9.

In Drupal 7 I added nodes programmatically with this PHP code:

<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$data = $_GET['d'];

AddNewNode($data);

function AddNewNode($data)
{
        list($installlanguage, $playerid) = explode('|', $data);
        $node = new stdClass();
        $node->type = 'new_install';
        node_object_prepare($node);
        $node->language = LANGUAGE_NONE;
        $node->field_hm_new_installlanguage[$node->language][0]['value'] = $installlanguage;
        $node->field_hm_new_install_playerid[$node->language][0]['value'] = $playerid;
        node_save($node);
}
?>

This code isn't working with Drupal 9.

I tried to search Google for "drupal 9 add content programmatically", but I don't seem to get any useful results. Most links are about Drupal 8.

Can someone point me in the right direction?

Thank you!

Jennifer
  • 45
  • 1
  • 7

3 Answers3

2

You can still do this if you really want. However, there are much better ways of managing content creation now (look at the examples for "migrate" module with e.g. JSON or CSV files).

The equivalent of what you have previously would be something like this;

<?php

use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$request = Request::createFromGlobals();
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();

defined('DRUPAL_ROOT') or define('DRUPAL_ROOT', getcwd());

$node = \Drupal::entityTypeManager()->getStorage('node')->create([
  'type'        => 'article',
  'title'       => 'something something',
  'langcode'    => 'en',
  'field_something' => ... // Check the structure as it differs between fields.
]);
// You don't have to do it all in one array.
$node->set('field_something_2', 'something');
$node->save();

Take a look here for more information https://drupalbook.org/drupal/9111-working-entity-fields-programmatically.

Pobtastic
  • 262
  • 2
  • 9
  • Thank you, very helpful! I wonder what part might be not required if you use that code within a PHP page ("within" the drupal site): Do you really have to (re)"boot" the kernel etc? Also, 'field_something', would it typically become 'body' or rather 'field_body' or even 'field_data_body' or...? – Max Jul 19 '22 at 09:45
  • I found both answers on https://blog.puppy.vn/md/drupal-9-create-simple-node-programatically : you only need `use Drupal\node\Entity\Node;` and it must be ` 'body' => [ 'summary' => '' , 'value' => $BODY , 'format' => 'full_html' ]` – Max Jul 19 '22 at 10:28
0

According to this blog post, the code is simpler (compared to @Pobtastic's answer) when you use it within a Drupal PHP page:

use Drupal\node\Entity\Node;
 
$node = Node::create([
  'type' => 'article',
  'langcode' => 'en',
  'title' => 'My test!',
  'body' => [
    'summary' => '',
    'value' => '<p>The body of my node.</p>',
    'format' => 'full_html',
  ],
]);
$node->save();
\\ Add URL alias :
\Drupal::service('path.alias_storage')->save("/node/" . $node->id(), "/my/path", "en");

Source:

Max
  • 415
  • 5
  • 12
0

There are 2 ways to create nodes programmatically in Drupal 8 and higher versions.

  • Using Entity Type Manager

    // Use the entity type manager (recommended).

    $node = \Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'article', 'title' => 'Another node']);

  • Using Node class

    use Drupal\node\Entity\Node;

    $node = Node::create([ 'type' => 'article', 'title' => 'The node title',]);

    // Save the node.

    $node->save();

Please refer to "Working with the Entity API" https://www.drupal.org/docs/drupal-apis/entity-api/working-with-the-entity-api#s-create