Skip to main content
added a note more about the suggested alternative
Source Link
avpaderno
  • 97.9k
  • 15
  • 164
  • 284

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

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.

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.

Source Link
avpaderno
  • 97.9k
  • 15
  • 164
  • 284

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.