Get navigationId from HttpCacheHitEvent in Shopware 6

Viewed 44

I have a subscriber that is listening to HttpCacheHitEvent and I would like to find the navigationId for the requested page.

For storefront events I use $event->getRequest()->getRequestUri(). But for this event i get URLs like /navigation/5943fc.... I currently use the basename() function to get the navigationIds of those URLs but that does not seem to be the clean way to do it.

Is there an alternative way to retrieve the navigationId from a HttpCacheHitEvent?

1 Answers

When you subscribe to this event you can't access the _route and other parameter attributes as usual, as the cached response will be returned before they are usually set.

$request = $event->getRequest();
var_dump($request->attributes->get('_route'));
// null

To solve that issue, you may inject the router service when registering your listener.

<service id="Foo\MyPlugin\CacheHitListener">
    <argument type="service" id="router"/>
    <tag name="kernel.event_subscriber"/>
</service>

In your listener you then retrieve your route parameters using the service and the request object from the event, so you can determine which route is being requested. Depending on the route, you can then go ahead and use parameters of the specific route.

class CacheHitListener implements EventSubscriberInterface
{
    private $matcher;

    /**
     * @param UrlMatcherInterface|RequestMatcherInterface $matcher
     */
    public function __construct($matcher)
    {
        $this->matcher = $matcher;
    }

    public static function getSubscribedEvents(): array
    {
        return [HttpCacheHitEvent::class => 'onCacheHit'];
    }

    public function onCacheHit(HttpCacheHitEvent $event): void
    {
        if ($this->matcher instanceof RequestMatcherInterface) {
            $parameters = $this->matcher->matchRequest($event->getRequest());
        } else {
            $parameters = $this->matcher->match($event->getRequest()->getPathInfo());
        }

        if ($parameters['_route'] === 'frontend.navigation.page') {
            $navigationId = $parameters['navigationId'];
            
            //...
        }
    }
}
Related