Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
By donpwinston on
RuntimeException: Failed to start the session because headers have already been sent by "/var/www/html/vendor/symfony/http-foundation/Response.php" at line 1239. in Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (line 152 of /var/www/html/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php)
This is the code that causes it:
<?php // $Id: SecureDistrictSubscriber.php,v 1.9 2022/05/04 10:51:16 dwinston Exp $
namespace Drupal\bncreports;
use Drupal\Core\Url;
use Drupal\user\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Prohibit access to other districts
*/
class SecureDistrictSubscriber implements EventSubscriberInterface
{
/**
* @param RequestEvent $event
*/
public function secureDistrict(RequestEvent $event): void
{
$current_user = User::load(\Drupal::currentUser()->id());
if ($current_user->hasRole('administrator') || $current_user->hasRole('bnc_operator') || $current_user->hasRole('ao_user'))
return;
$district_id = $current_user->get('field_district')->value;
if (!$district_id || strtolower($district_id) == 'all')
return;
$pathInfo = $event->getRequest()->getPathInfo();
if (preg_match('/\/users\/\d{3}(\d|[a-z]|\-)/', $pathInfo)) {
$params = explode('/', $pathInfo);
if ($district_id != $params[2]) {
$url = new Url('system.403');
$response = new RedirectResponse($url->toString(), 301);
$response->send();
}
} elseif (preg_match('/\/users/', $pathInfo)) {
$url = Url::fromUri('internal:/users/' . $district_id);
$response = new RedirectResponse($url->toString(), 301);
$response->send();
} elseif (preg_match('/\/user\/\d+\/edit/', $pathInfo)) {
$params = explode('/', $pathInfo);
$user = User::load($params[2]);
if ($district_id != $user->get('field_district')->value) {
$url = new Url('system.403');
$response = new RedirectResponse($url->toString(), 301);
$response->send();
} elseif (!$current_user->hasRole('district_poc') && $current_user->id() != $user->id()) {
$url = new Url('system.403');
$response = new RedirectResponse($url->toString(), 301);
$response->send();
}
}
}
/**
* Listen to kernel.request events and call secureDistrict.
* {@inheritdoc}
* @return array Event names to listen to (key) and methods to call (value)
*/
public static function getSubscribedEvents(): array
{
$events[KernelEvents::REQUEST][] = ['secureDistrict'];
return $events;
}
}
The user doesn't see the error and it doesn't appear to break anything but I would still like to fix it so the error doesn't occur.
Comments
Why do you think that code is
Why do you think that code is causing it?
That error often comes from having an echo statement in your code, inserting whitepace before the opening PHP tag, or using a closing PHP tag with whitespace after it. It will be in settings.php, or your custom code, or potentially a poorly coded contrib module or theme (if you're using any dev versions, you could look in there).
When I comment out $response-
When I comment out $response->send(); The RuntimeException is not logged.
Simpler is always better.
Maybe this can help: https:/
Maybe this can help: https://drupal.stackexchange.com/a/303653/66659
Strange Fix (Why?)
This made the problem go away. Got it from https://www.drupal.org/files/issues/2022-02-01/user_default_page_3257494...
Simpler is always better.
Proper Redirect Code
All of the above is incorrect. You have to use some middleware magic. I finally got it working properly with the following:
bncreports.services.yml
Simpler is always better.