0

I'm currently migrating a site to Drupal. The old site has thousands of dynamic URLs for which I cannot use a regular expression to handle them. Those URLs exist in a slightly different form in the Drupal site.
Unfortunately the URL structure is too complicated for being processed directly in a .htaccess file.

I want all the old URLs to return a 301 redirect to the new URL.

This is what I tried.

  • I implemented hook_page_preprocess() and sent a RedirectResponse to the new URL when the incoming URL matches the regular expression for the old URLs
  • I implemented an event subscriber that does basically the same on the onRequest event

In both the cases, the redirect response is sent with the following code.

$respond = new TrustedRedirectResponse($url,301);
$respond->send();
die();

Both solutions do work when the user is logged-in. In my local developing site, it works also when the user is not logged-in. On the live server, it doesn't work for anonymous users.

The funny thing is that, even when the redirection works for logged-in users, the log shows a Page not found entry for that URL. So it seems that even with the event subscriber solution, Drupal handles the 404 part first, and then executes my code.

What am I doing wrong?
Should I implement this differently?

2
  • Never use die() or send responses like that yourself. The event you have has a method to set a response object: Use that; see how the redirect.module does it, for example.
    – Berdir
    Commented Aug 26, 2017 at 12:28
  • I tried that too. Didn't change a thing. Commented Aug 26, 2017 at 17:55

1 Answer 1

2

I stumbled upon the same issue with Drupal 8.2.6: A 404 error was recorded even though my custom event subscriber was called.

Following what suggested in comments I read about the Redirect module, I set the event subscriber priority using the following code.

public static function getSubscribedEvents() {
  // This needs to run before RouterListener::onKernelRequest(), which has
  // a priority of 32. Otherwise, that aborts the request if no matching
  // route is found.
  $events[KernelEvents::REQUEST][] = array('onKernelRequest', 34);

  return $events;
}

This fixed the issue I was having.

Your Answer

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

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