diff --git a/composer.json b/composer.json
index 361149dd76932f2275b9e5897776a57aaf67ae1b..2d9519de8a8181d336e1eff30c2117c44daf0625 100644
--- a/composer.json
+++ b/composer.json
@@ -62,7 +62,7 @@
         "okvpn/clock-lts": "^1.0",
         "vlucas/phpdotenv": "^5.6",
         "edu-sharing/auth-plugin": "8.0.x-dev",
-        "psr/cache": "^1.0"
+        "psr/cache": "3.0.0"
     },
     "replace": {
         "symfony/polyfill-php73": "*",
diff --git a/composer.lock b/composer.lock
index bc0d599b24f436b46a8171a7ff270dea33694465..50868a9e43b6ca4c89340e733388d28a99c5436d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f50f62060597f2d86eb61fc8af9cf333",
+    "content-hash": "4f5e2e10224f8606704af0c8e80acc02",
     "packages": [
         {
             "name": "algo26-matthias/idna-convert",
@@ -740,56 +740,6 @@
             },
             "time": "2022-11-12T10:09:40+00:00"
         },
-        {
-            "name": "kub-at/php-simple-html-dom-parser",
-            "version": "1.9.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/Kub-AT/php-simple-html-dom-parser.git",
-                "reference": "ff22f98bfd9235115c128059076f3eb740d66913"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/Kub-AT/php-simple-html-dom-parser/zipball/ff22f98bfd9235115c128059076f3eb740d66913",
-                "reference": "ff22f98bfd9235115c128059076f3eb740d66913",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.2"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "KubAT\\PhpSimple\\HtmlDomParser": "src/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "S.C. Chen",
-                    "email": "me578022@gmail.com"
-                },
-                {
-                    "name": "Jakub Stawowy",
-                    "email": "Kub-AT@users.noreply.github.com"
-                }
-            ],
-            "description": "PHP Simple HTML DOM Parser with namespace and PHP 7.3 compatible",
-            "homepage": "http://simplehtmldom.sourceforge.net/",
-            "keywords": [
-                "Simple",
-                "dom",
-                "html"
-            ],
-            "support": {
-                "issues": "https://github.com/Kub-AT/php-simple-html-dom-parser/issues",
-                "source": "https://github.com/Kub-AT/php-simple-html-dom-parser/tree/master"
-            },
-            "time": "2019-10-25T12:34:43+00:00"
-        },
         {
             "name": "laravel/serializable-closure",
             "version": "v1.3.3",
@@ -2733,20 +2683,20 @@
         },
         {
             "name": "psr/cache",
-            "version": "1.0.1",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/cache.git",
-                "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
-                "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+                "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+                "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.0"
+                "php": ">=8.0.0"
             },
             "type": "library",
             "extra": {
@@ -2766,7 +2716,7 @@
             "authors": [
                 {
                     "name": "PHP-FIG",
-                    "homepage": "http://www.php-fig.org/"
+                    "homepage": "https://www.php-fig.org/"
                 }
             ],
             "description": "Common interface for caching libraries",
@@ -2776,9 +2726,9 @@
                 "psr-6"
             ],
             "support": {
-                "source": "https://github.com/php-fig/cache/tree/master"
+                "source": "https://github.com/php-fig/cache/tree/3.0.0"
             },
-            "time": "2016-08-06T20:24:11+00:00"
+            "time": "2021-02-03T23:26:27+00:00"
         },
         {
             "name": "psr/clock",
@@ -7252,58 +7202,57 @@
         },
         {
             "name": "symfony/cache",
-            "version": "v5.4.39",
+            "version": "v6.4.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "982237e35079fdcc31ab724f06b6131992c4fd24"
+                "reference": "b9e9b93c9817ec6c789c7943f5e54b57a041c16a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/982237e35079fdcc31ab724f06b6131992c4fd24",
-                "reference": "982237e35079fdcc31ab724f06b6131992c4fd24",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/b9e9b93c9817ec6c789c7943f5e54b57a041c16a",
+                "reference": "b9e9b93c9817ec6c789c7943f5e54b57a041c16a",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.2.5",
-                "psr/cache": "^1.0|^2.0",
+                "php": ">=8.1",
+                "psr/cache": "^2.0|^3.0",
                 "psr/log": "^1.1|^2|^3",
-                "symfony/cache-contracts": "^1.1.7|^2",
-                "symfony/deprecation-contracts": "^2.1|^3",
-                "symfony/polyfill-php73": "^1.9",
-                "symfony/polyfill-php80": "^1.16",
-                "symfony/service-contracts": "^1.1|^2|^3",
-                "symfony/var-exporter": "^4.4|^5.0|^6.0"
+                "symfony/cache-contracts": "^2.5|^3",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/var-exporter": "^6.3.6|^7.0"
             },
             "conflict": {
                 "doctrine/dbal": "<2.13.1",
-                "symfony/dependency-injection": "<4.4",
-                "symfony/http-kernel": "<4.4",
-                "symfony/var-dumper": "<4.4"
+                "symfony/dependency-injection": "<5.4",
+                "symfony/http-kernel": "<5.4",
+                "symfony/var-dumper": "<5.4"
             },
             "provide": {
-                "psr/cache-implementation": "1.0|2.0",
-                "psr/simple-cache-implementation": "1.0|2.0",
-                "symfony/cache-implementation": "1.0|2.0"
+                "psr/cache-implementation": "2.0|3.0",
+                "psr/simple-cache-implementation": "1.0|2.0|3.0",
+                "symfony/cache-implementation": "1.1|2.0|3.0"
             },
             "require-dev": {
                 "cache/integration-tests": "dev-master",
-                "doctrine/cache": "^1.6|^2.0",
                 "doctrine/dbal": "^2.13.1|^3|^4",
-                "predis/predis": "^1.1",
-                "psr/simple-cache": "^1.0|^2.0",
-                "symfony/config": "^4.4|^5.0|^6.0",
-                "symfony/dependency-injection": "^4.4|^5.0|^6.0",
-                "symfony/filesystem": "^4.4|^5.0|^6.0",
-                "symfony/http-kernel": "^4.4|^5.0|^6.0",
-                "symfony/messenger": "^4.4|^5.0|^6.0",
-                "symfony/var-dumper": "^4.4|^5.0|^6.0"
+                "predis/predis": "^1.1|^2.0",
+                "psr/simple-cache": "^1.0|^2.0|^3.0",
+                "symfony/config": "^5.4|^6.0|^7.0",
+                "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+                "symfony/filesystem": "^5.4|^6.0|^7.0",
+                "symfony/http-kernel": "^5.4|^6.0|^7.0",
+                "symfony/messenger": "^5.4|^6.0|^7.0",
+                "symfony/var-dumper": "^5.4|^6.0|^7.0"
             },
             "type": "library",
             "autoload": {
                 "psr-4": {
                     "Symfony\\Component\\Cache\\": ""
                 },
+                "classmap": [
+                    "Traits/ValueWrapper.php"
+                ],
                 "exclude-from-classmap": [
                     "/Tests/"
                 ]
@@ -7329,7 +7278,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v5.4.39"
+                "source": "https://github.com/symfony/cache/tree/v6.4.7"
             },
             "funding": [
                 {
@@ -7345,7 +7294,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-04-18T08:26:06+00:00"
+            "time": "2024-04-18T09:22:46+00:00"
         },
         {
             "name": "symfony/cache-contracts",
diff --git a/lib/classes/cache/Cache.class.php b/lib/classes/cache/Cache.class.php
index 366945dbcf6e4209c081a846f35dbf4494097de6..be703cf4ebce5bab8420efde06b5601de393c195 100644
--- a/lib/classes/cache/Cache.class.php
+++ b/lib/classes/cache/Cache.class.php
@@ -72,12 +72,12 @@ abstract class Cache implements CacheItemPoolInterface
     /**
      * @see CacheItemPoolInterface::getItem
      */
-    abstract public function getItem($key);
+    abstract public function getItem(string $key): CacheItemInterface;
 
     /**
      * @see CacheItemPoolInterface::hasItem
      */
-    abstract public function hasItem($key);
+    abstract public function hasItem(string $key): bool;
 
     /**
      * @var array An array of deferred items that shall be saved only
@@ -149,7 +149,7 @@ abstract class Cache implements CacheItemPoolInterface
     /**
      * @see CacheItemPoolInterface::getItems
      */
-    public function getItems(array $keys = [])
+    public function getItems(array $keys = []): iterable
     {
         $items = [];
         foreach ($keys as $key) {
@@ -164,45 +164,50 @@ abstract class Cache implements CacheItemPoolInterface
     /**
      * @see CacheItemPoolInterface::clear
      */
-    public function clear()
+    public function clear(): bool
     {
         $this->deferred_items = [];
         $this->flush();
+        return true;
     }
 
     /**
      * @see CacheItemPoolInterface::deleteItem
      */
-    public function deleteItem($key)
+    public function deleteItem($key): bool
     {
         $this->expire($key);
+        return true;
     }
 
     /**
      * @see CacheItemPoolInterface::deleteItems
      */
-    public function deleteItems(array $keys)
+    public function deleteItems(array $keys): bool
     {
         foreach ($keys as $key) {
             $this->expire($key);
         }
+        return true;
     }
 
     /**
      * @see CacheItemPoolInterface::saveDeferred
      */
-    public function saveDeferred(CacheItemInterface $item)
+    public function saveDeferred(CacheItemInterface $item): bool
     {
         $this->deferred_items[] = $item;
+        return true;
     }
 
     /**
      * @see CacheItemPoolInterface::commit
      */
-    public function commit()
+    public function commit(): bool
     {
         foreach ($this->deferred_items as $item) {
             $this->save($item);
         }
+        return true;
     }
 }
diff --git a/lib/classes/cache/DbCache.class.php b/lib/classes/cache/DbCache.class.php
index 3361af05a86fbba1127eaa79de8678e810cedbb8..c7abef22a7465c423dcf4cf7b2de85e867ef37b2 100644
--- a/lib/classes/cache/DbCache.class.php
+++ b/lib/classes/cache/DbCache.class.php
@@ -3,6 +3,7 @@
 namespace Studip\Cache;
 
 use DBManager;
+use Psr\Cache\CacheItemInterface;
 
 /**
  * StudipCache implementation using database table
@@ -88,7 +89,7 @@ class DbCache extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $query = "SELECT `content`, `expires`
                   FROM `cache`
@@ -114,7 +115,7 @@ class DbCache extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         $query = "SELECT 1
                   FROM `cache`
@@ -126,7 +127,7 @@ class DbCache extends Cache
     /**
      * @inheritDoc
      */
-    public function save(\Psr\Cache\CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         $expiration = $this->getExpiration($item);
         if ($expiration < 1) {
diff --git a/lib/classes/cache/FileCache.class.php b/lib/classes/cache/FileCache.class.php
index e94395ac46166c1993285de8301966c4a2b6794c..d760f08597111edeca131fc7801347d622955778 100644
--- a/lib/classes/cache/FileCache.class.php
+++ b/lib/classes/cache/FileCache.class.php
@@ -4,6 +4,7 @@ namespace Studip\Cache;
 
 use Config;
 use Exception;
+use Psr\Cache\CacheItemInterface;
 
 /**
  * Cache implementation using files
@@ -223,7 +224,7 @@ class FileCache extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $real_key = $this->getCacheKey($key);
 
@@ -251,7 +252,7 @@ class FileCache extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         $real_key = $this->getCacheKey($key);
         $file_data = $this->check($real_key);
@@ -261,7 +262,7 @@ class FileCache extends Cache
     /**
      * @inheritDoc
      */
-    public function save(\Psr\Cache\CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         $expiration = $this->getExpiration($item);
         if ($expiration < 1) {
diff --git a/lib/classes/cache/Item.class.php b/lib/classes/cache/Item.class.php
index 1a09f1ddd471a5005b9d8cd4eb8a9df43145ae09..4e83d4ddcebf5e43550c428f7c4e2c3efcb84a97 100644
--- a/lib/classes/cache/Item.class.php
+++ b/lib/classes/cache/Item.class.php
@@ -71,7 +71,7 @@ class Item implements CacheItemInterface
     /**
      * @inheritDoc
      */
-    public function getKey()
+    public function getKey(): string
     {
         return $this->key;
     }
@@ -79,7 +79,7 @@ class Item implements CacheItemInterface
     /**
      * @inheritDoc
      */
-    public function get()
+    public function get(): mixed
     {
         return $this->value;
     }
@@ -87,7 +87,7 @@ class Item implements CacheItemInterface
     /**
      * @inheritDoc
      */
-    public function isHit()
+    public function isHit(): bool
     {
         return $this->cache_hit;
     }
@@ -95,15 +95,16 @@ class Item implements CacheItemInterface
     /**
      * @inheritDoc
      */
-    public function set($value)
+    public function set($value): static
     {
         $this->value = $value;
+        return $this;
     }
 
     /**
      * @inheritDoc
      */
-    public function expiresAt($expiration)
+    public function expiresAt($expiration): static
     {
         $this->expiration = $expiration;
         return $this;
@@ -112,7 +113,7 @@ class Item implements CacheItemInterface
     /**
      * @inheritDoc
      */
-    public function expiresAfter($time)
+    public function expiresAfter($time): static
     {
         $this->expiration = new DateTime();
         if ($time instanceof DateInterval) {
diff --git a/lib/classes/cache/MemcachedCache.class.php b/lib/classes/cache/MemcachedCache.class.php
index 5d9033be9b8c71f947cea88260e26f1fe8a8d09c..1c4b685b0c2c409fbdc10355b4aeaa82d8064d17 100644
--- a/lib/classes/cache/MemcachedCache.class.php
+++ b/lib/classes/cache/MemcachedCache.class.php
@@ -114,7 +114,7 @@ class MemcachedCache extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $item = new Item($key);
         $value = $this->memcache->get($this->getCacheKey($key));
@@ -129,7 +129,7 @@ class MemcachedCache extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         return $this->memcache->checkKey($this->getCacheKey($key));
     }
@@ -137,7 +137,7 @@ class MemcachedCache extends Cache
     /**
      * @inheritDoc
      */
-    public function save(CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         $expiration = $this->getExpiration($item);
         if ($expiration < 1) {
diff --git a/lib/classes/cache/MemoryCache.class.php b/lib/classes/cache/MemoryCache.class.php
index 93f6bbd66aa9429e62a8fc48d755b95fab2f24eb..7c00753ea9a187ca5543ece8bb9ee7d7b3df1ad9 100644
--- a/lib/classes/cache/MemoryCache.class.php
+++ b/lib/classes/cache/MemoryCache.class.php
@@ -19,11 +19,11 @@ class MemoryCache extends Cache
     /**
      * Expires just a single key.
      *
-     * @param  string  the key
+     * @param  string $arg the key
      */
-    public function expire($key)
+    public function expire($arg)
     {
-        unset($this->memory_cache[$key]);
+        unset($this->memory_cache[$arg]);
     }
 
     /**
@@ -52,7 +52,7 @@ class MemoryCache extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $item = new Item($key);
         if (!isset($this->memory_cache[$key])) {
@@ -75,7 +75,7 @@ class MemoryCache extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         return isset($this->memory_cache[$key])
             && $this->memory_cache[$key]['expires'] < time();
@@ -84,7 +84,7 @@ class MemoryCache extends Cache
     /**
      * @inheritDoc
      */
-    public function save(CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         $expiration = $this->getExpiration($item);
 
diff --git a/lib/classes/cache/Proxy.class.php b/lib/classes/cache/Proxy.class.php
index 6791fb72c93a245ed7c6338848163c3a358c4af4..fef034d2bb59c05ea90de2add61b832180638ffb 100644
--- a/lib/classes/cache/Proxy.class.php
+++ b/lib/classes/cache/Proxy.class.php
@@ -2,6 +2,7 @@
 
 namespace Studip\Cache;
 
+use Psr\Cache\CacheItemInterface;
 use StudipCacheOperation;
 
 /**
@@ -39,20 +40,20 @@ class Proxy extends Cache
     /**
      * Expires just a single key.
      *
-     * @param string $key The item's key
+     * @param string $arg The item's key
      */
-    public function expire($key)
+    public function expire($arg)
     {
         if (in_array('expire', $this->proxy_these)) {
             try {
-                $operation = new StudipCacheOperation([$key, 'expire']);
+                $operation = new StudipCacheOperation([$arg, 'expire']);
                 $operation->parameters = serialize([]);
                 $operation->store();
-            } catch (\Exception $e) {
+            } catch (\Exception) {
             }
         }
 
-        return $this->actual_cache->expire($key);
+        return $this->actual_cache->expire($arg);
     }
 
     /**
@@ -65,7 +66,7 @@ class Proxy extends Cache
                 $operation = new StudipCacheOperation(['', 'flush']);
                 $operation->parameters = serialize([]);
                 $operation->store();
-            } catch (\Exception $e) {
+            } catch (\Exception) {
             }
         }
 
@@ -90,7 +91,7 @@ class Proxy extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         return $this->actual_cache->getItem($key);
     }
@@ -98,7 +99,7 @@ class Proxy extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         return $this->actual_cache->hasItem($key);
     }
@@ -106,14 +107,14 @@ class Proxy extends Cache
     /**
      * @inheritDoc
      */
-    public function save(\Psr\Cache\CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         if (in_array('save', $this->proxy_these)) {
             try {
                 $operation = new StudipCacheOperation([$item->getKey(), 'save']);
                 $operation->parameters = serialize([$item]);
                 $operation->store();
-            } catch (\Exception $e) {
+            } catch (\Exception) {
             }
         }
 
diff --git a/lib/classes/cache/RedisCache.class.php b/lib/classes/cache/RedisCache.class.php
index 9ea871146222b71444b0d1c48248323c46df83d3..a78f7510804d3c75dbb174aba4eb366026692dd2 100644
--- a/lib/classes/cache/RedisCache.class.php
+++ b/lib/classes/cache/RedisCache.class.php
@@ -156,7 +156,7 @@ class RedisCache extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $item = new Item($key);
         $real_key = $this->getCacheKey($key);
@@ -175,7 +175,7 @@ class RedisCache extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         $real_key = $this->getCacheKey($key);
         return $this->redis->get($real_key) !== null;
@@ -184,7 +184,7 @@ class RedisCache extends Cache
     /**
      * @inheritDoc
      */
-    public function save(CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         $expiration = $this->getExpiration($item);
         if ($expiration < 1) {
diff --git a/lib/classes/cache/Wrapper.class.php b/lib/classes/cache/Wrapper.class.php
index 744893270b1ccb2e05987b87992921686282356c..4e6342cd4f2425d332a54207fee39de4097d8246 100644
--- a/lib/classes/cache/Wrapper.class.php
+++ b/lib/classes/cache/Wrapper.class.php
@@ -59,7 +59,7 @@ class Wrapper extends Cache
     /**
      * @inheritDoc
      */
-    public function getItem($key)
+    public function getItem(string $key): CacheItemInterface
     {
         $cached = $this->memory_cache->getItem($key);
         if ($cached->isHit()) {
@@ -76,7 +76,7 @@ class Wrapper extends Cache
     /**
      * @inheritDoc
      */
-    public function hasItem($key)
+    public function hasItem(string $key): bool
     {
         return $this->actual_cache->hasItem($key);
     }
@@ -84,7 +84,7 @@ class Wrapper extends Cache
     /**
      * @inheritDoc
      */
-    public function save(CacheItemInterface $item)
+    public function save(CacheItemInterface $item): bool
     {
         if ($this->actual_cache->save($item)) {
             return $this->memory_cache->save($item);