<?php declare(strict_types = 1);
namespace App\Doctrine\Cache;
use App\Doctrine\Common\Cache\TaggedMemcachedCache;
use App\Entity\DealBid;
use App\Entity\ProjectBid;
use App\Entity\ProposalBid;
use App\Event\CreditsEvent;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class InvalidateListener implements EventSubscriberInterface
{
private TaggedMemcachedCache $taggedCache;
private bool $enabled = true;
public function __construct(TaggedMemcachedCache $taggedCache)
{
$this->taggedCache = $taggedCache;
}
/**
* note this listener is auto-removed if we do not use result_cache: service in doctrine config
*
* @see \App\DependencyInjection\Compiler\RemoveInvalidateListenerPass
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
* @param LifecycleEventArgs<ObjectManager> $args
* @param object $entity
*/
public function postUpdate($entity, LifecycleEventArgs $args): void
{
if (!$this->enabled) {
return;
}
$className = get_class($entity);
$entityManager = $args->getObjectManager();
$metadata = $entityManager->getClassMetadata($className);
if (!isset($metadata->cache['region'])) {
return;
}
/** @var string $modelKey */
$modelKey = $metadata->cache['region'];
$this->taggedCache->removeTag($modelKey);
if ($modelKey === 'cache_project' || $modelKey === 'cache_deal' || $modelKey === 'cache_shop_video' || $modelKey === 'feed') {
$this->taggedCache->removeTag('categorization');
}
}
public function setEnabled(bool $enabled): void
{
$this->enabled = $enabled;
}
public function onCredits(CreditsEvent $event): void
{
$related = $event->getRelatedEntity();
if (!$related instanceof ProposalBid) {
return;
}
switch (ClassUtils::getClass($related)) {
case DealBid::class:
$modelKey = 'cache_deal';
break;
case ProjectBid::class:
$modelKey = 'cache_project';
break;
default:
throw new UnexpectedTypeException($related, DealBid::class . '|' . ProjectBid::class);
}
$this->taggedCache->removeTag($modelKey);
}
/**
* @return array<string, array<int|string, array<int|string, int|string>|int|string>|string>
*/
public static function getSubscribedEvents(): array
{
return [
CreditsEvent::class => ['onCredits', -255],
];
}
}