4

I have a module that in hook_preprocess() checks with drupal_get_http_header() whether Drupal is returning a 403 or 404 error, but in Drupal 8 that function is deprecated, since header handling is being shifted to a Symfony response object.

I am using code similar to the following one.

$header = drupal_get_http_header('Status');

switch ($header) {
  case '403 Forbidden':
    // Add new headers.
    // …
    break;

  case '404 Not Found':
    // Add new headers.
    // …
    break;
}

What code should I use in Drupal 8? If that means to use a different hook, that is fine.

I would also be interested in the case I need to add HTML output to the page. I guess that in this case I should use hook_page_alter(), but I still don't know how to access the response object for the page being served.

2

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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