How to bootstrap a custom script and retrieve the session object?
-
18-02-2021 - |
Вопрос
I'm writing a custom script that requires a proper Drupal 8 user session to work. This is the current version:
<?php
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
$drupal_root = __DIR__;
define('DRUPAL_DIR', $drupal_root);
// Specify relative path to the drupal root.
$autoloader = require_once DRUPAL_DIR . '/autoload.php';
$request = Request::createFromGlobals();
// Bootstrap drupal to different levels
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();
$kernel->handlePageCache($request);
$kernel->prepareLegacyRequest($request);
// get session handler and retrieve session details
$session_handler = \Drupal::getContainer()->get('session_handler.storage');
$session_id = $session_handler->getId();
$logged_in = (bool) $session_handler->read($session_id);
// inspect values
var_dump($request->getSession());
var_dump($session_id);
var_dump($logged_in); exit;
I'd expect $request->getSession()
to return something, $session_id
to be the Drupal's session id, and the $logged_in
variable to be truthy. Instead I keep getting this output:
NULL string(0) "" bool(false)
Update 1: I executed this on a browser, which I have an active session with my Drupal. This script is placed in a subfolder of the Drupal installation, so it should not be a cookie path issue.
Update 2: Added var_dump($request->getSession())
to the script.
Решение
This is the code I came up with in the end. It works.
Feel free to suggest a more concise version :-)
<?php
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
$drupal_root = realpath(__DIR__ . '/../');
$autoloader = require_once $drupal_root . '/autoload.php';
// Make sure Drupal operates correct when handle request instead of internal server error and twig error
chdir($drupal_root);
$kernel = new DrupalKernel('prod', $autoloader);
// Note: The session_name is generated from the string "{domain}/{script basepath}".
// Need to override the script filename and script name before creating request.
$_SERVER['SCRIPT_FILENAME'] = $drupal_root . '/index.php';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$request = Request::createFromGlobals();
// Note: may restore script_name and script_filename after this line.
// This handle process would chain up and initialize all services
// in container, include the session handler.
$kernel->handle($request);
// now we can use session normally
$session_handler = \Drupal::getContainer()->get('session_handler.storage');
$session_id = $session_handler->getId();
$logged_in = (bool) $session_handler->read($session_id);
// restore app
chdir(__DIR__);
Не связан с drupal.stackexchange