. */ declare(strict_types=1); namespace App\EntityListeners; use App\Entity\Base\AbstractDBElement; use App\Entity\Base\AbstractStructuralDBElement; use App\Entity\LabelSystem\LabelProfile; use App\Entity\UserSystem\Group; use App\Entity\UserSystem\User; use App\Services\UserSystem\UserCacheKeyGenerator; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Mapping as ORM; use function get_class; use Symfony\Contracts\Cache\TagAwareCacheInterface; class TreeCacheInvalidationListener { protected TagAwareCacheInterface $cache; protected UserCacheKeyGenerator $keyGenerator; public function __construct(TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) { $this->cache = $treeCache; $this->keyGenerator = $keyGenerator; } /** * @ORM\PostUpdate() * @ORM\PostPersist() * @ORM\PostRemove() */ public function invalidate(AbstractDBElement $element, LifecycleEventArgs $event): void { //If an element was changed, then invalidate all cached trees with this element class if ($element instanceof AbstractStructuralDBElement || $element instanceof LabelProfile) { $secure_class_name = str_replace('\\', '_', get_class($element)); $this->cache->invalidateTags([$secure_class_name]); //Trigger a sidebar reload for all users (see SidebarTreeUpdater service) if(!$element instanceof LabelProfile) { $this->cache->invalidateTags(['sidebar_tree_update']); } } //If a user change, then invalidate all cached trees for him if ($element instanceof User) { $secure_class_name = str_replace('\\', '_', get_class($element)); $tag = $this->keyGenerator->generateKey($element); $this->cache->invalidateTags([$tag, $secure_class_name]); } /* If any group change, then invalidate all cached trees. Users Permissions can be inherited from groups, so a change in any group can cause big permisssion changes for users. So to be sure, invalidate all trees */ if ($element instanceof Group) { $tag = 'groups'; $this->cache->invalidateTags([$tag]); } } }