Drupal Answers Asked on October 26, 2021
Context : I use the following code to replace a token by a rendered node.
The resulted text is sent by email
$renderable = $view_builder->view($node, 'token', $langcode);
$replacements[$original] = Drupal::service('renderer')->renderPlain($renderable);
This is working fine except when I am queuing the mails to be sent
Because, in this case, the upper code runs in a queue and NodeAccessControlHandler::checkAccess
and NodeAccessControlHandler::checkFieldAccess
are called with an anonymous account (id=0).
This leads to an AccessRessult::forbidden()
(because in my setup, anonymous can’t see those fields and/or this node) and the rendered node is empty…
Thus my question is:
How to render a node (in a queue) "in behalf of" an admin user?
or
How to explain to my overrided NodeAccessControlHandler
that we are in a queue and that it can safely give access (without security concerns)
Thanks to the comment of @No Sssweat I could find a solution:
Summary: the problem appeared when emails were sent via a queue in a cron. The cron is running as an anonymous user, and, in this case, the drupal viewBuilder/Rendering system doesn't have enough permission to display some fields/nodes.
Solution: Adapt the processItem
function of the QueueWorker in order to switch the current user into an admin user at the beginning of the process and switch back at the end.
I my use case, I overrode the QueueWorker provided by another module. Here is my code with the injection of the switcher service: (feel free to comment)
/**
* The account switcher service.
*
* @var DrupalCoreSessionAccountSwitcherInterface
*/
protected $accountSwitcher;
public function __construct(array $configuration, $plugin_id, $plugin_definition, SubscribersInterface $subscribers, AccountSwitcherInterface $account_switcher)
{
parent::__construct($configuration, $plugin_id, $plugin_definition, $subscribers);
$this->accountSwitcher = $account_switcher;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
{
return new static($configuration, $plugin_id, $plugin_definition, $container->get('message_subscribe.subscribers'), $container->get('account_switcher'));
}
public function processItem($data)
{
$this->accountSwitcher->switchTo(new UserSession([
'uid' => 1,
'name' => 'cron_admin',
'roles' => ['administrator'],
]));
parent::processItem($data);
$this->accountSwitcher->switchBack();
}
Answered by Baud on October 26, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP