diff --git a/src/EntityListeners/TreeCacheInvalidationListener.php b/src/EntityListeners/TreeCacheInvalidationListener.php index e18e936d..79a6aab2 100644 --- a/src/EntityListeners/TreeCacheInvalidationListener.php +++ b/src/EntityListeners/TreeCacheInvalidationListener.php @@ -36,6 +36,7 @@ use App\Entity\Base\DBElement; use App\Entity\Base\StructuralDBElement; use App\Entity\UserSystem\Group; use App\Entity\UserSystem\User; +use App\Services\UserCacheKeyGenerator; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\PostFlushEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; @@ -45,10 +46,12 @@ use Symfony\Contracts\Cache\TagAwareCacheInterface; class TreeCacheInvalidationListener { protected $cache; + protected $keyGenerator; - public function __construct(TagAwareCacheInterface $treeCache) + public function __construct(TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) { $this->cache = $treeCache; + $this->keyGenerator = $keyGenerator; } /** @@ -69,7 +72,7 @@ class TreeCacheInvalidationListener //If a user change, then invalidate all cached trees for him if ($element instanceof User) { - $tag = "user_" . $element->getUsername(); + $tag = $this->keyGenerator->generateKey($element); $this->cache->invalidateTags([$tag]); } diff --git a/src/Services/ToolsTreeBuilder.php b/src/Services/ToolsTreeBuilder.php index b0efce04..bfc7e414 100644 --- a/src/Services/ToolsTreeBuilder.php +++ b/src/Services/ToolsTreeBuilder.php @@ -45,17 +45,18 @@ class ToolsTreeBuilder protected $translator; protected $urlGenerator; - protected $security; + protected $keyGenerator; protected $cache; public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $urlGenerator, - TagAwareCacheInterface $treeCache, Security $security) + TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) { $this->translator = $translator; $this->urlGenerator = $urlGenerator; - $this->security = $security; $this->cache = $treeCache; + + $this->keyGenerator = $keyGenerator; } /** @@ -65,13 +66,11 @@ class ToolsTreeBuilder */ public function getTree() : array { - $username = $this->security->getUser()->getUsername(); + $key = "tree_tools_" . $this->keyGenerator->generateKey(); - $key = "tree_tools_" . $username; - - return $this->cache->get($key, function (ItemInterface $item) use ($username) { + return $this->cache->get($key, function (ItemInterface $item) { //Invalidate tree, whenever group or the user changes - $item->tag(["tree_tools", "groups", "user_" . $username]); + $item->tag(["tree_tools", "groups", $this->keyGenerator->generateKey()]); $tree = array(); $tree[] = new TreeViewNode($this->translator->trans('tree.tools.edit'), null, $this->getEditNodes()); diff --git a/src/Services/TreeBuilder.php b/src/Services/TreeBuilder.php index dadf2c24..a5ea2c95 100644 --- a/src/Services/TreeBuilder.php +++ b/src/Services/TreeBuilder.php @@ -60,15 +60,15 @@ class TreeBuilder protected $em; protected $translator; protected $cache; - protected $security; + protected $keyGenerator; public function __construct(EntityURLGenerator $URLGenerator, EntityManagerInterface $em, - TranslatorInterface $translator, TagAwareCacheInterface $treeCache, Security $security) + TranslatorInterface $translator, TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator) { $this->url_generator = $URLGenerator; $this->em = $em; $this->translator = $translator; - $this->security = $security; + $this->keyGenerator = $keyGenerator; $this->cache = $treeCache; } @@ -174,15 +174,14 @@ class TreeBuilder */ public function typeToNodesList(string $class_name, ?StructuralDBElement $parent = null): array { - $username = $this->security->getUser()->getUsername(); $parent_id = $parent != null ? $parent->getID() : "0"; // Backslashes are not allowed in cache keys $secure_class_name = str_replace("\\", '_', $class_name); - $key = "list_" . $username . "_" . $secure_class_name . $parent_id; + $key = "list_" . $this->keyGenerator->generateKey() . "_" . $secure_class_name . $parent_id; - $ret = $this->cache->get($key, function (ItemInterface $item) use ($class_name, $parent, $secure_class_name, $username) { + $ret = $this->cache->get($key, function (ItemInterface $item) use ($class_name, $parent, $secure_class_name) { // Invalidate when groups, a element with the class or the user changes - $item->tag(['groups', 'tree_list', 'user_' . $username, $secure_class_name]); + $item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]); /** * @var $repo StructuralDBElementRepository */ diff --git a/src/Services/UserCacheKeyGenerator.php b/src/Services/UserCacheKeyGenerator.php new file mode 100644 index 00000000..5582ae91 --- /dev/null +++ b/src/Services/UserCacheKeyGenerator.php @@ -0,0 +1,73 @@ +security = $security; + } + + /** + * Generates a key for the given user. + * @param User|null $user The user for which the key should be generated. When set to null, the currently logged in + * user is used. + * @return string + */ + public function generateKey(User $user = null) : string + { + //If no user was specified, use the currently used one. + if ($user === null) { + $user = $this->security->getUser(); + } + + //If the user is null, then treat it as anonymous user. + //When the anonymous user is passed as user then use this path too. + if ($user === null || $user->getID() === User::ID_ANONYMOUS) { + return 'user$_' . User::ID_ANONYMOUS; + } + + //In the most cases we can just use the username (its unique) + return "user_" . $user->getUsername(); + } +} \ No newline at end of file