0

A similar question was posted here: EventSubscriber endless redirect

But I haven't quite been able to implement a workable solution.

On Drupal 8.73: Basically we have a custom module that is redirecting to clean urls (so that /node/42 doesn't get indexed by google). I didn't write the module and I'm a little fuzzy on what it's doing and why. The module works fine except that urls with ? in them endlessly redirect and get caught in a redirect loop. The browser eventually returns an error that the page is redirecting and will never load properly. Here is the module:

<?php

/**
 * @file
 * Contains \Drupal\mymodule\EventSubscriber\MyModuleSubscriber.
 */

namespace Drupal\sjwc_tweaks\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;


/**
 * Event subscriptions for events dispatched by SimpleFbConnect.
 */
class TweaksSubscriber implements EventSubscriberInterface {

  public function onRequest(GetResponseEvent $event) {
    $baseUrl = $event->getRequest()->getBaseUrl();
    $attr = $event->getRequest()->attributes;
    if (null !== $attr && null !== $attr->get('node') && $attr->get('_controller') == '\Drupal\node\Controller\NodeViewController::view') {
      $node = $attr->get('node');
      $nid = $node->id();
      $current_uri = \Drupal::request()->getRequestUri();
      if (\Drupal::service('path.matcher')->isFrontPage()) {
        $redirect_uri = '/';
      } else {
        $url = Url::fromRoute('entity.node.canonical', ['node' => $nid]);
        $redirect_uri = $url->toString();
      }
      if ($redirect_uri != $current_uri) {
        $event->setResponse(new RedirectResponse($redirect_uri));
      }
    }
  }

  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['onRequest'];
    return $events;
  }

}

I believe this line is the issue:

$event->setResponse(new RedirectResponse($redirect_uri));

At the issue linked above, a kind user suggested a solution that I do not quite understand, they said:

The problem is, you should never send a response inside of a StackPHP application. Drupal continues to build its own response (the real frontpage) and stores this in the cache. Set the response in the event instead: $event->setResponse($response);

I'm not sure exactly where he means by setting the response "in the event" instead.

Now, as this issue only is a problem on urls with ? in them, I did find I could correct the issue by wrapping the line above, line 37 thusly:

if (strpos($current_uri, '?') != TRUE) {
  $event->setResponse(new RedirectResponse($redirect_uri));
}

However I worry this might cause unpredictable behavior and I prefer to fix this the right way the first time. Can someone tell me what I'm doing wrong or overlooking or explain how I can "set the response in the event" instead?

2

1 Answer 1

0

You can try to manually add the query parameters to the redirect URL.

Add this code:

$query = [];
parse_str($current_uri, $query);

just below this code:

$current_uri = \Drupal::request()->getRequestUri();

And then change this line:

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid]);

To this:

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid], ['query' => $query]);

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.