0

I've installed Drupal 8, I've created a PHP file to read a XML file and insert some items, but I'm getting this error.

Fatal error: Uncaught Error: Class 'Drupal\node\Entity\Node' not found in C:\xampp\htdocs\drupal8\migracion.php:12 Stack trace: #0 {main} thrown in C:\xampp\htdocs\drupal8\migracion.php on line 12

This is the code I am using.

define('DRUPAL_DIR', __DIR__);
use \Drupal\Core\DrupalKernel;
use \Symfony\Component\HttpFoundation\Request;
use \Drupal\node\Entity\Node;
use \Drupal\file\Entity\File;
use \Drupal\pathauto\PathautoState;

$fileContentXML = file_get_contents(DRUPAL_DIR . "/sites/default/files/migration/data.xml");
$xml_file = simplexml_load_string($fileContentXML);
foreach ($xml_file->channel->item as $item) {
  $node = Node::create(['type' => 'article']);
  $nid = trim($item->nid);
  $node->set('nid', $nid);
  $node->set('uid', 1);
  $node->enforceIsNew();
  $node->save();
}

How can I fix this error?

3
  • Did you try typing a \ before "Drupal"? "use \Drupal\node\Entity\Node;"
    – julianx2rl
    Feb 2, 2021 at 21:24
  • yes i've already tried, use \Drupal\node\Entity\Node; but i still get that error Feb 2, 2021 at 21:45
  • 2
    You need to include the composer autoload file to your script as it doesn't know where to find the namespacea Feb 3, 2021 at 7:39

1 Answer 1

2

The code shown in the question doesn't bootstrap Drupal, nor does it load the Node module. An external script needs to do that, differently from a module.

I usually use the authenticate.php file as guideline for writing code for an external script file that needs to bootstrap Drupal.

use Drupal\Core\DrupalKernel;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\NodeInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Route;

// Change the directory to the Drupal root.
// Edit the following line to make it point to the directory containing the autoload.php file.
chdir('.');
$autoloader = (require_once 'autoload.php');

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

  // A route is required for route matching.
  $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('<none>'));
  $request->attributes->set(RouteObjectInterface::ROUTE_NAME, '<none>');
  $kernel->preHandle($request);

  // Ensure our request includes the session if appropriate.
  if (PHP_SAPI !== 'cli') {
    $request->setSession($kernel->getContainer()->get('session'));
  }
} catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());
  $response->prepare($request)->send();
  exit;
}

\Drupal::moduleHandler()->addModule('system', 'core/modules/system');
\Drupal::moduleHandler()->addModule('node', 'core/modules/node');
\Drupal::moduleHandler()->load('system');
\Drupal::moduleHandler()->load('node');

$xml = simplexml_load_string(file_get_contents('./sites/default/files/migration/data.xml'));
foreach ($xml->channel->item as $item) {
  $node = \Drupal::entityManager()->getStorage('node')->create(
    'type' => 'article',
    'nid' => (int)$item->nid,
    'uid' => 1,
    'status' => NodeInterface::PUBLISHED
  ]);
  if ($node) {
    // The following line isn't necessary, as create() already calls enforceIsNew(). 
    // $node->enforceIsNew();
    $node->save();
  }
}

As side note, Drupal 8 has a migration system. Instead of using an external script that bootstraps Drupal, it would be better to use that. Depending on the migration, that may require to write a custom module. Even in that case, this route is preferable, as most of the migration code has been already written.

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.