3

Community asked.. Please clarify your specific problem...

Fair comment. What I'd like help with is how do I correct the script below so it works with D9.

<?php


use Drupal\Core\DrupalKernel;

$autoloader = require_once 'autoload.php';

// This next line is the problem
$request = Request::createFromGlobals();


$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');

$kernel->boot();

require_once 'core/includes/database.inc';
require_once 'core/includes/schema.inc';


$em = $kernel->getContainer()->get('entity_type.manager');

$entity = $em->getStorage('node')->create(array(

    'type'        => 'article',
    'title'       => 'Druplicon test',
    
 ));       


$entity->save();

?>

This is the same as the D8 script below which works - except I have:

  • removed the use symphony line;
  • replaced the deprecated function ( thanks leymannx )

The script fails as noted on the line
$request = Request::createFromGlobals(); with messages

chrome-error://chromewebdata/:1 Failed to load resource: the server responded with a status of 500 () VM10:7288 crbug/1173575, non-JS module files deprecated.

Can someone point out what's wrong with this line in D9 (which I guess relates to the removal of the symphony use statement) and also if there are any other lines of code following which D9 won't like.

Thanks for any further help on this and apologies for the earlier confusion and for still being out of my depth with D9.


Original post...

This article provides D8 code to create an entity from an external script. I'm in the same boat as the person who asked this question - wanting to convert from D7's drupal_bootstrap.

Although my requirement is D9, I thought I'd try and get a D8 script working using the above post. His application is with an entity. I'm wanting to create article entries.

Here is the code I took from the above link which is said to work..

<?php

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

require_once 'core/includes/database.inc';
require_once 'core/includes/schema.inc';

$em = $kernel->getContainer()->get('entity.manager');

$entity = $em->getStorage('node')->create(array(

    'type'        => 'article',
    'title'       => 'Druplicon test',
    
 ));       

$entity->save();

?>

This code runs and creates an entry in the node_field_data table but the article is not listed as content on the site.

I'm very much feeling my way with D8/D9 coding so please bear with me if I'm doing something silly!

Once I can get this to work, I then need to find out what changes are needed for D9 - so any help here would be good. For example the D8 code uses symphony but that's not part of D9 I believe.

Thanks for any help on this to get this to work. And to help me replace my D7 experience with D8/D9!

Sorry... This code does show up in the content - I was looking at a D9 site, not the test D8 I set up. Apologies!

But I'd still like help on what changes I need to make to this script to run under D9.

10
  • 1
    entity.manager is deprecated use entity_type.manager instead.
    – leymannx
    Commented Nov 10, 2021 at 21:50
  • "create an entity from an external script" - what would be the reason for doing this?
    – Joseph
    Commented Nov 10, 2021 at 21:51
  • 1
    You can "sync" data using Migrate and scheduled cron. I've done this on several projects. The benefit to this is it will handle virtually everything for you.
    – Kevin
    Commented Nov 11, 2021 at 1:35
  • 1
    Thanks Kevin - Migrate (core module) is something I know nothing about. Syncing! Sounds brilliant. I'll check it out. The cron bit is what I've used with an external script, drupal_bootstrap.
    – peter300
    Commented Nov 11, 2021 at 12:01
  • 1
    There are several examples out there. Look at Migrate Plus module.
    – Kevin
    Commented Nov 11, 2021 at 12:59

1 Answer 1

3

Here is the code that allows entity creation in a D9 site from a remote script - run from the same domain as the D9 site but not from the D9 root directory.

<?php
//drupal root directory
chdir('/var/www/vhosts/example.org/httpdocs/dev3');

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

require_once 'core/includes/schema.inc';

$em = $kernel->getContainer()->get('entity_type.manager');

$entity = $em->getStorage('node')->create([
  'type'        => 'article',
  'title'       => 'Druplicon test' . date("d/m/Y")." ". date("h:i:sa"),
]);

$entity->save();

?>

The clue to this code came from this article which explains the way Drupal loads a page. It says "look at index.php in the root, if you want to see how Drupal does it". About 6 lines of code!

Why didn't my earlier script, ported from D8, work? Here are some of the things I learned:

  • the line $request = Request::createFromGlobals(); which stopped the earlier script running works ok in this code;
  • there is no file database.inc in the root directory on a D9 site;
  • I changed the deprecated entity.manager to entity_type_manager as leymannx advised;
  • D9 does seem to use Symphony - it appears in index.php in release 9.2.7. But it's a later version than D8;
  • the external script should not be in the Drupal root - not even for testing - otherwise the site fires with a 404;
  • If you want to Google for information on bootstrapping, don't use Bootstrap - otherwise all you see is info. on the theme!

Getting this working means I can replace D7 external scripts with D9. I take the point kevin makes about using the migrate module but I think bootstrapping a better solution for my use cases. E.g a user adds a record to a MySQL database in Microsoft Access under program control. The code then runs an external script to add selected fields to a Drupal entity. Immediately the Access user and the web user see the same up-to-date data.

Thanks to everyone who contributed on this. I hope this post clears up the messy way I started this question.

1
  • Are you people facing Error: Class 'Drupal\mysql\Driver\Database\mysql\Connection' not found... error now? Any work around? Commented Jun 23, 2022 at 14:31

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.