5

I have a module in drupal8 which only job is on an event response is to redirect a URL. It works fine for everyone except anonymous users. How do I give the module privileges to fire on every user no matter if the are logged in or not.

This is the geographic_me_redirect.services.yml

services:
  me_redirect.process_me_request:
    class: Drupal\me_redirect\EventSubscriber\ResponseSubscriber
    arguments: []
    tags:
      - { name: event_subscriber }

This is the response

class ResponseSubscriber implements EventSubscriberInterface
{


    /**
     * Constructor.
     */
    public function __construct()
    {

    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {

        ///$events[KernelEvents::REQUEST][] = ['onRouteMatch', 27];
        //-- fires the event in the kernal early oo page load 20
        $events[KernelEvents::RESPONSE] = ['process_language_request',0];
        //-- For redirecting to another domain

        return $events;
    }



    public function process_language_request(FilterResponseEvent $event)
    {

    return my logic

    }
}
1
  • Can you explain more about method process_language_request, condition, process you want?
    – Jonh
    Commented Jan 13, 2017 at 10:23

2 Answers 2

3

You can't do this when the redirect is already stored in the internal page cache. Because anonymous traffic is served from this cache before any event is fired.

You have to use this kill switch:

\Drupal::service('page_cache_kill_switch')->trigger();

If you put this in your event subscriber and clear the cache, then you prevent, that the response is cached in the internal page cache.

2
  • Not sure where others have placed \Drupal::service('page_cache_kill_switch')->trigger(); but it worked for me to add to the constructor __construct().
    – Duncanmoo
    Commented Jul 17, 2018 at 7:16
  • 1
    @Duncanmoo, while you can use this kill switch almost anywhere, I meant with event subscriber in this example process_language_request(FilterResponseEvent $event), not the class, because you can put multiple event subscribers in one class.
    – 4uk4
    Commented Jul 17, 2018 at 7:58
0

If you just want redirect to URL you can use class like this:

<?php

namespace Drupal\my_event\EventSubscriber;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Class MyEventSubscriber.
 *
 * @package Drupal\my_event
 */
class MyEventSubscriber implements EventSubscriberInterface {


  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['processEvent', 0];
    return $events;
  }

  /**
   * Redirect and cache with anonymous user
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   * @param \Drupal\Core\Url $url
   */
  protected function setResponse(GetResponseEvent $event, Url $url) {
    $response = new TrustedRedirectResponse($url->toString(), 301);
    $response->addCacheableDependency(CacheableMetadata::createFromRenderArray([])
      ->addCacheTags(['rendered']));
    $event->setResponse($response);
  }

  /**
   * Process with difference condition
   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
   */
  public function processEvent(GetResponseEvent $event) {
    $logic = $this->checkLogic();
    if ($logic) {
      $this->setResponse($event, Url::fromUri("https://www.example.com"));
    }
  }

  /**
   * Check logic redirect
   * @return boolean logic
   */
  protected function checkLogic() {
    return $logic;
  }
}

Magic here is method setResponse. I use event KernelEvents::REQUEST and set cache in method setResponse. It's working with anonymous user.

2
  • Hi, this is working great except for the redirects keeps looping could you give me an example inside the checklogic(). I am assuming that it stops an. The redirect from looping. Also with this could use $response = new RedirectResponse($url); $response->send();
    – purencool
    Commented Jan 16, 2017 at 2:26
  • what's condition you want redirect to url?
    – MrD
    Commented Jan 17, 2017 at 6:54

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.