Drupal - How can I convert the code that used drupal_get_http_header() to check if a 403 or 404 error is returned?

You can subscribe to the Symfony KernelEvents::RESPONSE event:

The RESPONSE event occurs once a response was created for replying to a request

This event allows you to modify or replace the response that will be replied. The event listener method receives a Symfony\Component\HttpKernel\Event\FilterResponseEvent instance.

To do so, create a new module ("response_test" in this example), with the usual .info.yml and .module file.

Then register your event subscriber in the module's services file:

response_test.services.yml

services:
    response_test.response_subscriber:
      class: Drupal\response_test\ResponseSubscriber
      tags:
        - { name: event_subscriber }

Now all you need is the class to handle the event:

lib/Drupal/response_test/ResponseSubscriber.php

<?php 

namespace Drupal\response_test;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ResponseSubscriber implements EventSubscriberInterface {
  
  public function onRespond(FilterResponseEvent $event) {
    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
      return;
    }
    
    $response = $event->getResponse();
    if ($response->getStatusCode() == 404) {
      // Prepare a new Symfony\Component\HttpFoundation\Response and use
      $event->setResponse($new_response);

      // or call one of the setter methods on $response, the changes will persist
    }
  }
  
  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('onRespond');
    return $events;
  }
  
}

I'm a little unsure about changing the HTML content in this context; you have access to $response->getContent() and $response->setContent() so you can manipulate the raw string directly, but as far as I can tell everything's already rendered at this point.


To check for error codes you can use the following snippet. It won't work for 200 status codes though. Since there's no exception.

use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

$exception = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception');
if ($exception instanceof HttpExceptionInterface) {
  $status_code = $exception->getStatusCode();
  // ...
}

I'm unsure if it's safe to assume that the status code must be 200 if there's no exception in the first place. If yes you could use the following snippet to cover a 200er response.

if (!\Drupal::requestStack()->getCurrentRequest()->attributes->has('exception')) {
  $status_code = '200';
}

Tags:

8

Hooks