Search code examples
symfonyresponsesymfony4

Symfony EventSubscriber: The Page isn't redirecting properly


I have been recently researching EventListeners for the kernal for Symfony4 and I thought I had grasped the basic concept of it but I seem to get a page isn't redirecting properly issue with my EventSubscriber.

Essentially I'd like to do the following logic:

if file_exists $file
    redirect to file
else
    carry on as normal

Which is how I originally came to kernel.response. Here is my current code:

<?php
namespace App\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class MaintenanceSubscriber implements EventSubscriberInterface
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        if (!$event->isMasterRequest()) {
            return;
        }

        if (file_exists('maintenance.flag')) {
            $response = new RedirectResponse('maintenance');
            $event->setResponse($response);
        }
    }

    public static function getSubscribedEvents()
    {
        return array(
            KernelEvents::RESPONSE => 'onKernelResponse'
        );
    }
}

this does my logic more or less perfectly, when maintenance.flag doesn't exist it carries on the project as expected, but when I touch maintenance.flag it gets the infamous Firefox page of Page isn't redirecting properly.

I'm not sure if I'm missing something?

I've set up my route:

maintenance:
    path: /maintenance
    controller: App\Controller\Maintenance\FlagController::flag

which is just a render function - I have a feeling that this could be causing the issue (an endless loop of redirect to flag() which then performs the before action?) but I'm not sure how to render my template from the setResponse() method

Even with the routing conf commented out, I still get the error. So not 100% sure anymore that it's the flag() endless loop theory


Solution

  • I was right indeed about the endless loop being the issue, adding this conditional to exclude the /maintenance url got it to work:

    if (strpos($event->getRequest()->getRequestUri(), 'maintenance') !== false) {
        return;
    }