英文:
Shopware 6 - cache key of logged in storefront user
问题
有没有办法找出已登录的前端用户的完整缓存密钥?任务是在客户购买产品后,在产品列表和详细页面上显示特定信息。因此,我们需要在客户购买产品后清除特定的缓存。
英文:
Is there a way to figure out the full cache key of a logged in frontend user?
The task is to dispay a specific info on the product listing and on the detail page after a customer has bought the product. So we need to clear the specific cache after the customer bought a product.
答案1
得分: 1
你可以注入 CacheInvalidator
并自行使带有产品 ID 标记的缓存条目失效。
use Shopware\Core\Framework\Adapter\Cache\CacheInvalidator;
use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
class CacheInvalidatorService
{
public function __construct(private readonly CacheInvalidator $cacheInvalidator)
{
}
public function invalidate(string $productId): void
{
$this->cacheInvalidator->invalidate([EntityCacheKeyGenerator::buildProductTag($productId)]);
}
}
如果你有一个通用的值,每次购买后都会更新,比如每次购买都会增加的计数器之类的东西,这应该足够了。
客户本身没有特定的缓存键。否则每个单独的客户都会有一个缓存条目,这实际上违反了缓存的原则。所以,如果你想显示完全针对客户的内容,比如客户以前是否购买过该产品,你可以监听特定的页面加载事件,例如 ProductPageLoadedEvent
。在订阅器中,你可以使用当前客户,获取额外的数据并将其添加为扩展。对于已登录的客户,默认情况下应该绕过 HTTP 缓存,响应(包括产品)将成为上述事件的一部分。
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded',
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
// 可能之前已被缓存的对象
$page = $event->getPage();
$customer = $event->getSalesChannelContext()->getCustomer();
$product = $page->getProduct();
if (!$customer) {
return;
}
// 处理客户和产品
// ...
// 将额外的数据作为扩展添加到模板中
$page->addExtension('myExtension', $someExtension);
}
}
英文:
You can inject CacheInvalidator
and invalidate the cache entries tagged with the product id yourself.
use Shopware\Core\Framework\Adapter\Cache\CacheInvalidator;
use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
class CacheInvalidatorService
{
public function __construct(private readonly CacheInvalidator $cacheInvalidator)
{
}
public function invalidate(string $productId): void
{
$this->cacheInvalidator->invalidate([EntityCacheKeyGenerator::buildProductTag($productId)]);
}
}
This should suffice if you have a generic value that updates after each purchase, like a counter increasing with each purchase or something.
The customer itself has no specific cache key. Otherwise there would be a cache entry for every single customer, essentially contradicting the principle of caching. So if you want to display something entirely customer specific, like if a customer has bought the product before, you can listen to the specific page load event, e.g. ProductPageLoadedEvent
. In the subscriber you can then use the current customer, fetch additional data and add it as extension. With a logged-in customer the http cache should be circumvented by default and the object-cached response, including the product(s) will be part of the aforementioned events.
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded',
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
// the object that could've previously been cached
$page = $event->getPage();
$customer = $event->getSalesChannelContext()->getCustomer();
$product = $page->getProduct();
if (!$customer) {
return;
}
// do something with the customer and product
// ...
// add additional data as extension for use in the template
$page->addExtension('myExtension', $someExtension);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论