0

When this code is executed, I have an error message logged.
The code is in shared_node_access(NodeInterface $node, $op, AccountInterface $account)

if ($node->get('nid')->value == 1) {
  if ($account->isAnonymous()) {
  }
  else {
    $path = Url::fromUserInput('/node/25')->toString();
    $response = new RedirectResponse($path);
    $response->send();
  }
}

The error message:

RuntimeException : Failed to start the session because headers have already been sent by "/home/lejardindf/JdP8/vendor/symfony/http-foundation/Response.php" at line 377. dans Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (/home/lejardindf/JdP8/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php ligne 150)

0

2 Answers 2

0

There are two problems. First, you can't send a response from custom Drupal code. Second, you can't run non access code in an access hook, because access results are cached.

For redirects in Drupal 8 see these change records: drupal_goto() has been removed and hook_init() removed.

A different approach might be to let the 403 exception happen and then catch it in an exception event subscriber to do the redirect, see How to redirect an anonymous user to the login form after a 403 error?

2
  • what do you mean by "you can't send a response from custom Drupal code"? And on that "drupal_goto() removed" page there's a snippet "Drupal 8 procedural" that looks similar to the above, essentially (new RedirectResponse($path))->send();. However, if I put this in a page, I do get the "Failed to start...because headers have already been sent" error.
    – Max
    Aug 13, 2022 at 17:10
  • @Max , this is not a good code example. There is no way to send a response from within a Symfony app, you have to return it from the controller. For other places see drupal.stackexchange.com/a/304037/47547
    – 4uk4
    Aug 13, 2022 at 18:18
0

Following @4k4's advice, I removed the code from shared_node_access.
Then added shared.services.yml:

services:
  shared.event_subscriber:
    class: Drupal\shared\EventSubscriber\EventSubscriber
    arguments: ['@current_user']
    tags:
      - { name: event_subscriber }

and EventSubscriber.php:

class EventSubscriber implements EventSubscriberInterface {

  protected $currentUser;

  public function __construct(AccountInterface $current_user) {
    $this->currentUser = $current_user;
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['redirectIf'];
    return $events;
  }

  public function redirectIf(FilterResponseEvent $event) {
    $node = $event->getRequest()->attributes->get('node');
    if ($node && $node->get('nid')->value == 1) {
      if (!$this->currentUser->isAnonymous()) {
        $path = Url::fromUserInput('/node/25')->toString();
        $event->setResponse(new RedirectResponse($path));
      }
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.