<?php
/*
* Author: Dominik Piekarski <code@dompie.de>
* Created at: 2021/10/13 12:08
*/
declare(strict_types=1);
namespace App\Subscriber\Messenger;
use App\Dto\PregenerateMessengerCacheDto;
use App\Entity\ConversationRoute;
use App\Event\Messenger\ConversationDeleteEvent;
use App\Event\Messenger\ConversationRouteChangeEvent;
use App\Event\Messenger\ConversationStartEvent;
use App\Event\Messenger\MessengerEventInterface;
use App\Event\Messenger\NewMessageEvent;
use App\Event\Messenger\RouteReadEvent;
use App\Pure\Builder\PureConversationBuilder;
use App\Service\Messenger\MessengerCacheService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
class MessengerCacheSubscriber implements EventSubscriberInterface
{
protected MessengerCacheService $messengerCache;
protected PureConversationBuilder $builder;
protected array $filtersToClear = [
PureConversationBuilder::FILTER_ALL,
PureConversationBuilder::FILTER_UNREAD,
PureConversationBuilder::FILTER_READ,
PureConversationBuilder::FILTER_UNANSWERED_BY_ME,
PureConversationBuilder::FILTER_ANSWERED_BY_ME,
PureConversationBuilder::FILTER_SEARCH,
PureConversationBuilder::FILTER_TRASH,
];
public function __construct(PureConversationBuilder $builder, MessengerCacheService $messengerCache)
{
$this->messengerCache = $messengerCache;
$this->builder = $builder;
}
public static function getSubscribedEvents(): array
{
return [
ConversationStartEvent::class => [['onConversationStartClearCache', 0]],
ConversationRouteChangeEvent::class => [['onConversationRouteHiddenClearCache', 0]],
ConversationDeleteEvent::class => [['onConversationDeleteClearCache', 0]],
RouteReadEvent::class => [['onConversationRouteReadEventClearCache', 0]],
NewMessageEvent::class => [['onMessageEventClearCache', 0]],
TerminateEvent::class => [['onTerminatePregenerateCaches', 0]],
];
}
/**
* @throws \Psr\Cache\InvalidArgumentException
*/
public function onConversationRouteReadEventClearCache(RouteReadEvent $event): void
{
$route = $event->getEntity();
$recipient = $route->getToMember();
$this->messengerCache->clearConversationsCacheForMemberFilter($recipient->getId(), $this->filtersToClear);
}
/**
* @throws \Psr\Cache\InvalidArgumentException
*/
public function onConversationRouteHiddenClearCache(ConversationRouteChangeEvent $event): void
{
$conversationRoute = $event->getEntity();
$this->messengerCache->clearConversationsCacheForMember($conversationRoute->getToMember()->getId());
$this->messengerCache->clearConversationsCacheForMember($conversationRoute->getFromMember()->getId());
}
/**
* @throws \Psr\Cache\InvalidArgumentException
*/
public function onConversationStartClearCache(MessengerEventInterface $event): void
{
/** @var ConversationRoute $conversationRoute */
$conversationRoute = $event->getEntity()->getRoutes()->first();
$this->messengerCache->clearConversationsCacheForMemberFilter($conversationRoute->getToMember()->getId(), $this->filtersToClear);
$this->messengerCache->clearConversationsCacheForMemberFilter($conversationRoute->getFromMember()->getId(), $this->filtersToClear);
}
public function onConversationDeleteClearCache(ConversationDeleteEvent $event): void
{
$this->messengerCache->clearMessagesCacheForConversation($event->getId());
}
public function onMessageEventClearCache(MessengerEventInterface $event): void
{
/** @var ConversationRoute $conversationRoute */
$conversationRoute = $event->getEntity()->getConversation()->getRoutes()->first();
$this->messengerCache->clearMessagesCacheForConversation($conversationRoute->getConversation()->getId());
$this->messengerCache->clearConversationsCacheForMemberFilter($conversationRoute->getToMember()->getId(), $this->filtersToClear);
$this->messengerCache->clearConversationsCacheForMemberFilter($conversationRoute->getFromMember()->getId(), $this->filtersToClear);
}
public function onTerminatePregenerateCaches(TerminateEvent $event): void
{
$request = $event->getRequest();
$pregenCacheDto = $request->attributes->get('pregenerateCache');
if (!$event->isMainRequest() || 200 !== $event->getResponse()->getStatusCode() || !$pregenCacheDto instanceof PregenerateMessengerCacheDto) {
return;
}
if ($pregenCacheDto->isTypeConversationList()) {
foreach ($pregenCacheDto->getPages() as $page) {
$this->builder->getCachedConversationList($pregenCacheDto->getMember(), $page, $pregenCacheDto->getFilter());
}
return;
}
}
}