For a plugin I need to manipulate a product price dynamically. I a customer calls the product URL with the parameter ?price=special
the price needs to be manipulated on the detail page and on every following request everywhere in the shop (slider on CMS pages, listing, detail page, cart, search, etc.) if a specific session key is set.
The logic works (when in dev environment with no HTTP cache), but not in production.
If I manipulate the product price for customer A, the product page will be cached with the lowered price and customer B will get the price of customer A.
I decorated the CacheStateValidator
to skip the HTTP cache when the customer has a matching session key, but even with the deactivated HTTP cache my EntityLoadedEvent
(product.loaded
) is not dispatched when it is already cached from another customer.
I also tried a CustomProductPriceCalculator
(as seen in the Dev-Docs about Price Calculation), but the caching problems persist.
- What would be the best way to disabled this second (ObjectCache?) cache?
- What is the best way to manipulate single product prices dynamically?
Update 08.04.2023
I created a subscriber for the following events and tried to disable the StoreApiRouteCache:
public static function getSubscribedEvents(): array
{
return [
ProductDetailRouteCacheKeyEvent::class => 'onCacheKeyEvent',
ProductListingRouteCacheKeyEvent::class => 'onCacheKeyEvent',
ProductSearchRouteCacheKeyEvent::class => 'onCacheKeyEvent',
ProductSuggestRouteCacheKeyEvent::class => 'onCacheKeyEvent',
CrossSellingRouteCacheKeyEvent::class => 'onCacheKeyEvent',
];
}
public function onCacheKeyEvent(StoreApiRouteCacheKeyEvent $event): void
{
if ($this->sessionKeyExists) {
$event->disableCaching();
}
}
When I open the product without the session key in two browsers (Firefox, Chrome) I see the normal price in both browsers. If I add the session key in Chrome and reload both browsers, I see the updated price in both browsers.
I tested the Chrome requests with xdebug and the $event->disableCaching();
method is called.