From c659d71e33cecbe42a7038c281c082f4b5c98414 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Mon, 6 May 2024 08:50:32 +0000
Subject: [PATCH] adjustments for php8, fixes #4111

Closes #4111

Merge request studip/studip!2956
---
 lib/activities/Stream.php                     | 30 ++-------
 lib/classes/Config.class.php                  | 30 ++-------
 lib/classes/ForumHelpers.php                  | 10 +--
 lib/classes/I18NString.php                    |  7 +--
 .../Middlewares/StudipMockNavigation.php      | 27 ++------
 lib/classes/MultiDimArrayObject.class.php     | 13 +---
 lib/classes/Request.class.php                 | 27 ++------
 lib/classes/SemClass.class.php                | 22 ++-----
 lib/classes/SemType.class.php                 | 27 +++-----
 lib/classes/SessionDecoder.class.php          | 61 ++++---------------
 lib/classes/StudipArrayObject.class.php       | 38 ++----------
 lib/classes/StudipCachedArray.php             |  7 +--
 lib/classes/StudipPDO.class.php               | 33 ++++------
 lib/classes/StudipPDOStatement.php            |  5 +-
 lib/classes/UserDataAdapter.php               | 30 ++-------
 lib/classes/restapi/Response.php              | 24 ++------
 .../sidebar/AttributesArrayAccessTrait.php    | 26 ++------
 lib/filesystem/StandardFile.php               | 21 ++-----
 lib/filesystem/UnknownFileType.php            | 21 ++-----
 lib/models/DataField.class.php                |  5 +-
 lib/models/SimpleCollection.class.php         | 12 +---
 lib/models/SimpleORMap.class.php              | 41 +++----------
 lib/models/SimpleORMapCollection.class.php    |  5 +-
 lib/navigation/Navigation.php                 |  7 +--
 phpstan-php8.neon.dist                        | 26 --------
 phpstan.neon.dist                             |  2 +-
 26 files changed, 114 insertions(+), 443 deletions(-)
 delete mode 100644 phpstan-php8.neon.dist

diff --git a/lib/activities/Stream.php b/lib/activities/Stream.php
index 6b64eff6cfb..b1472eff430 100644
--- a/lib/activities/Stream.php
+++ b/lib/activities/Stream.php
@@ -79,66 +79,48 @@ class Stream implements \ArrayAccess, \Countable, \IteratorAggregate
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->activities[$offset]);
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->activities[$offset];
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->activities[$offset] = $value;
     }
 
     /**
      * ArrayAccess: unset the value at the given offset (not applicable)
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         unset($this->activities[$offset]);
     }
 
     /**
      * IteratorAggregate
-     *
-     * @todo Add \Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): \Traversable
     {
         return new \ArrayIterator($this->activities);
     }
 
     /**
      * Countable
-     *
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->activities);
     }
diff --git a/lib/classes/Config.class.php b/lib/classes/Config.class.php
index 4d57f0f3338..2f6b728fd03 100644
--- a/lib/classes/Config.class.php
+++ b/lib/classes/Config.class.php
@@ -153,11 +153,8 @@ class Config implements ArrayAccess, Countable, IteratorAggregate
 
     /**
      * IteratorAggregate
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         return new ArrayIterator($this->data);
     }
@@ -188,55 +185,40 @@ class Config implements ArrayAccess, Countable, IteratorAggregate
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->$offset);
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->$offset;
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->$offset = $value;
     }
 
     /**
      * ArrayAccess: unset the value at the given offset (not applicable)
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
 
     }
 
     /**
      * Countable
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->data);
     }
diff --git a/lib/classes/ForumHelpers.php b/lib/classes/ForumHelpers.php
index 3054dbc8ea4..0c036cf3a17 100644
--- a/lib/classes/ForumHelpers.php
+++ b/lib/classes/ForumHelpers.php
@@ -92,19 +92,15 @@ class ForumHelpers {
      */
     public static function translate_perm($perm)
     {
-        $mapping = [
+        return match ($perm) {
             'root'   => _('Root'),
             'admin'  => _('Administrator/-in'),
             'dozent' => _('Lehrende/-r'),
             'tutor'  => _('Tutor/-in'),
             'autor'  => _('Autor/-in'),
             'user'   => _('Leser/-in'),
-        ];
-
-        // TODO: Activate next when devboard reliably runs on PHP7
-        // return $mapping[$perm] ?? '';
-
-        return isset($mapping[$perm]) ? $mapping[$perm] : '';
+            default  => '',
+        };
     }
 
     /**
diff --git a/lib/classes/I18NString.php b/lib/classes/I18NString.php
index 63e275e29c4..eab42ff4cc6 100644
--- a/lib/classes/I18NString.php
+++ b/lib/classes/I18NString.php
@@ -78,13 +78,8 @@ class I18NString implements JsonSerializable
 
     /**
      * Return the JSON representation of this i18n field in selected language.
-     *
-     * @return string
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function jsonSerialize()
+    public function jsonSerialize(): string
     {
         return (string) $this;
     }
diff --git a/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php b/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
index 34225d4ad83..088380929a3 100644
--- a/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
+++ b/lib/classes/JsonApi/Middlewares/StudipMockNavigation.php
@@ -18,53 +18,38 @@ class DummyNavigation extends \Navigation implements \ArrayAccess
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return true;
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this;
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
     }
 
     /**
      * ArrayAccess: Delete the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
     }
 
     /**
-     * IteratorAggregate: Create interator for request parameters.
-     *
-     * @todo Add \Traversable return type when Stud.IP requires PHP8 minimal
+     * IteratorAggregate: Create iterator for request parameters.
      */
-    #[\ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): \Traversable
     {
         return new \ArrayIterator();
     }
diff --git a/lib/classes/MultiDimArrayObject.class.php b/lib/classes/MultiDimArrayObject.class.php
index 459578f5ca6..b578018ca2c 100644
--- a/lib/classes/MultiDimArrayObject.class.php
+++ b/lib/classes/MultiDimArrayObject.class.php
@@ -78,13 +78,8 @@ class MultiDimArrayObject extends StudipArrayObject
 
     /**
      * Create a new iterator from an ArrayObject instance
-     *
-     * @return \Iterator
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         $class = $this->iteratorClass;
 
@@ -96,12 +91,8 @@ class MultiDimArrayObject extends StudipArrayObject
      *
      * @param  mixed $key
      * @param  mixed $value
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($key, $value)
+    public function offsetSet($key, $value): void
     {
         $new_value = $this->recursiveArrayToArrayObjects($value);
         if (is_array($new_value)) {
diff --git a/lib/classes/Request.class.php b/lib/classes/Request.class.php
index c9779346c61..d72a6a991d5 100644
--- a/lib/classes/Request.class.php
+++ b/lib/classes/Request.class.php
@@ -45,55 +45,40 @@ class Request implements ArrayAccess, IteratorAggregate
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->params[$offset]);
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->params[$offset] ?? null;
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->params[$offset] = $value;
     }
 
     /**
      * ArrayAccess: Delete the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         unset($this->params[$offset]);
     }
 
     /**
-     * IteratorAggregate: Create interator for request parameters.
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
+     * IteratorAggregate: Create iterator for request parameters.
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         return new ArrayIterator((array)$this->params);
     }
diff --git a/lib/classes/SemClass.class.php b/lib/classes/SemClass.class.php
index 09580e20444..c4a2c26cd0f 100644
--- a/lib/classes/SemClass.class.php
+++ b/lib/classes/SemClass.class.php
@@ -478,11 +478,8 @@ class SemClass implements ArrayAccess
      * deprecated, does nothing, should not be used
      * @param string $offset
      * @param mixed $value
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
     }
 
@@ -490,12 +487,8 @@ class SemClass implements ArrayAccess
      * Compatibility function with old $SEM_CLASS variable for plugins. Maps the
      * new array-structure to the old boolean values.
      * @param integer $offset: name of attribute
-     * @return boolean|(localized)string
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         switch ($offset) {
             case "name":
@@ -528,12 +521,8 @@ class SemClass implements ArrayAccess
     /**
      * ArrayAccess method to check if an attribute exists.
      * @param int $offset
-     * @return bool
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->data[$offset]);
     }
@@ -541,11 +530,8 @@ class SemClass implements ArrayAccess
     /**
      * deprecated, does nothing, should not be used
      * @param string $offset
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
     }
 
diff --git a/lib/classes/SemType.class.php b/lib/classes/SemType.class.php
index 3d5de5d94fd..2365c4e8e93 100644
--- a/lib/classes/SemType.class.php
+++ b/lib/classes/SemType.class.php
@@ -86,8 +86,8 @@ class SemType implements ArrayAccess
         if ($this->countSeminars() === 0) {
             $db = DBManager::get();
             $statement = $db->prepare("
-                DELETE FROM sem_types 
-                WHERE id = :id 
+                DELETE FROM sem_types
+                WHERE id = :id
             ");
             StudipCacheFactory::getCache()->expire('DB_SEM_TYPES_ARRAY');
             return $statement->execute([
@@ -119,11 +119,9 @@ class SemType implements ArrayAccess
      * deprecated, does nothing, should not be used
      * @param string $offset
      * @param mixed $value
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+
+    public function offsetSet($offset, $value): void
     {
     }
 
@@ -131,12 +129,8 @@ class SemType implements ArrayAccess
      * Compatibility function with old $SEM_TYPE variable for plugins. Maps the
      * new array-structure to the old boolean values.
      * @param integer $offset: name of attribute
-     * @return boolean|(localized)string
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         switch ($offset) {
             case "name":
@@ -153,12 +147,8 @@ class SemType implements ArrayAccess
     /**
      * ArrayAccess method to check if an attribute exists.
      * @param mixed $offset
-     * @return bool
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->data[$offset]);
     }
@@ -166,11 +156,8 @@ class SemType implements ArrayAccess
     /**
      * deprecated, does nothing, should not be used
      * @param string $offset
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
     }
 
diff --git a/lib/classes/SessionDecoder.class.php b/lib/classes/SessionDecoder.class.php
index 8c0bc6b9c7d..d437494cf9c 100644
--- a/lib/classes/SessionDecoder.class.php
+++ b/lib/classes/SessionDecoder.class.php
@@ -83,69 +83,42 @@ class SessionDecoder implements ArrayAccess, Countable, Iterator {
         return $this->var_names;
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function rewind()
+    public function rewind(): void
     {
         reset($this->var_names);
     }
 
-    /**
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function current()
+    public function current(): mixed
     {
         $current = current($this->var_names);
         return $current !== false ? $this->offsetGet($current) : false;
     }
 
-    /**
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function key()
+    public function key(): mixed
     {
         return current($this->var_names);
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function next()
+    public function next(): void
     {
         next($this->var_names);
     }
 
-    /**
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function valid()
+    public function valid(): bool
     {
         $current = current($this->var_names);
         return $current !== false;
     }
 
-    /**
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->encoded_session[$offset]);
     }
 
     /**
-     * @param $offset
-     * @return mixed|null
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
+     * @param string $offset
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         if($this->offsetExists($offset) && !isset($this->decoded_session[$offset])) {
             $this->decoded_session[$offset] = unserialize($this->encoded_session[$offset]);
@@ -153,27 +126,15 @@ class SessionDecoder implements ArrayAccess, Countable, Iterator {
         return $this->decoded_session[$offset] ?? null;
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
     }
 
-    /**
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->var_names);
     }
diff --git a/lib/classes/StudipArrayObject.class.php b/lib/classes/StudipArrayObject.class.php
index fe9aad17622..531da670d8d 100644
--- a/lib/classes/StudipArrayObject.class.php
+++ b/lib/classes/StudipArrayObject.class.php
@@ -157,13 +157,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
 
     /**
      * Get the number of public properties in the ArrayObject
-     *
-     * @return int
-     *
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->storage);
     }
@@ -216,13 +211,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
 
     /**
      * Create a new iterator from an ArrayObject instance
-     *
-     * @return \Iterator
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         $class = $this->iteratorClass;
 
@@ -273,12 +263,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
      * Returns whether the requested key exists
      *
      * @param  mixed $key
-     * @return bool
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($key)
+    public function offsetExists($key): bool
     {
         return isset($this->storage[$key]);
     }
@@ -287,12 +273,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
      * Returns the value at the specified key
      *
      * @param  mixed $key
-     * @return mixed
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($key)
+    public function offsetGet($key): mixed
     {
         $ret = null;
         if (!$this->offsetExists($key)) {
@@ -308,12 +290,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
      *
      * @param  mixed $key
      * @param  mixed $value
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($key, $value)
+    public function offsetSet($key, $value): void
     {
         if (is_null($key)) {
             $this->append($value);
@@ -326,12 +304,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
      * Unsets the value at the specified key
      *
      * @param  mixed $key
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($key)
+    public function offsetUnset($key): void
     {
         if ($this->offsetExists($key)) {
             unset($this->storage[$key]);
diff --git a/lib/classes/StudipCachedArray.php b/lib/classes/StudipCachedArray.php
index 18bb55b7086..1232d00950d 100644
--- a/lib/classes/StudipCachedArray.php
+++ b/lib/classes/StudipCachedArray.php
@@ -71,13 +71,8 @@ class StudipCachedArray implements ArrayAccess
      * Returns the value at given offset or null if it doesn't exist.
      *
      * @param string $offset Offset
-     *
-     * @return mixed
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         $this->loadData($offset);
         return $this->data[$offset];
diff --git a/lib/classes/StudipPDO.class.php b/lib/classes/StudipPDO.class.php
index e77a37fc5f0..8fa3418bf95 100644
--- a/lib/classes/StudipPDO.class.php
+++ b/lib/classes/StudipPDO.class.php
@@ -122,23 +122,20 @@ class StudipPDO extends PDO
      * Quotes the given value in a form appropriate for the type.
      * If no explicit type is given, the value's PHP type is used.
      *
-     * @param mixed $value PHP value to quote
+     * @param mixed $string PHP value to quote
      * @param ?int $type parameter type (e.g. PDO::PARAM_STR)
      * @return string|false quoted SQL string
-     *
-     * @todo Add string|false return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function quote($value, $type = null)
+    public function quote($string, $type = null): false|string
     {
         if (!isset($type)) {
-            if (is_null($value)) {
+            if (is_null($string)) {
                 $type = PDO::PARAM_NULL;
-            } else if (is_bool($value)) {
+            } else if (is_bool($string)) {
                 $type = PDO::PARAM_BOOL;
-            } else if (is_int($value)) {
+            } else if (is_int($string)) {
                 $type = PDO::PARAM_INT;
-            } else if (is_array($value)) {
+            } else if (is_array($string)) {
                 $type = StudipPDO::PARAM_ARRAY;
             } else {
                 $type = PDO::PARAM_STR;
@@ -149,28 +146,24 @@ class StudipPDO extends PDO
             case PDO::PARAM_NULL:
                 return 'NULL';
             case PDO::PARAM_BOOL:
-                return $value ? '1' : '0';
+                return $string ? '1' : '0';
             case PDO::PARAM_INT:
-                return (int) $value;
+                return (int) $string;
             case StudipPDO::PARAM_ARRAY:
-                return is_array($value) && count($value) ? join(',', array_map([$this, 'quote'], $value)) : 'NULL';
+                return is_array($string) && count($string) ? join(',', array_map([$this, 'quote'], $string)) : 'NULL';
             case StudipPDO::PARAM_COLUMN:
-                return preg_replace('/\\W/', '', $value);
+                return preg_replace('/\\W/', '', $string);
             default:
-                return parent::quote($value);
+                return parent::quote($string);
         }
     }
 
     /**
      * Executes an SQL statement and returns the number of affected rows.
      *
-     * @param string    SQL statement
-     * @return int|false      number of affected rows
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
+     * @param string $statement SQL statement
      */
-    #[ReturnTypeWillChange]
-    public function exec($statement)
+    public function exec(string $statement): false|int
     {
         $this->verify($statement);
         return parent::exec($statement);
diff --git a/lib/classes/StudipPDOStatement.php b/lib/classes/StudipPDOStatement.php
index 4a3d0697de6..80a8dc8c558 100644
--- a/lib/classes/StudipPDOStatement.php
+++ b/lib/classes/StudipPDOStatement.php
@@ -99,11 +99,8 @@ class StudipPDOStatement implements IteratorAggregate
 
     /**
      * Forwards all Iterator methods to the actual statement object.
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         return $this->stmt;
     }
diff --git a/lib/classes/UserDataAdapter.php b/lib/classes/UserDataAdapter.php
index 0a0c3beab2b..52771450dc5 100644
--- a/lib/classes/UserDataAdapter.php
+++ b/lib/classes/UserDataAdapter.php
@@ -26,66 +26,48 @@ class UserDataAdapter implements ArrayAccess, Countable, IteratorAggregate
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return $this->user->offsetExists($this->adaptOffset($offset));
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->user->offsetGet($this->adaptOffset($offset));
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->user->offsetSet($this->adaptOffset($offset), $value);
     }
 
     /**
      * ArrayAccess: unset the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         $this->user->offsetUnset($this->adaptOffset($offset));
     }
 
     /**
      * @see Countable::count()
-     *
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return $this->user->count();
     }
 
     /**
      * @see IteratorAggregate::getIterator()
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         return $this->user->getIterator();
     }
diff --git a/lib/classes/restapi/Response.php b/lib/classes/restapi/Response.php
index 4417979baf8..56d9b653407 100644
--- a/lib/classes/restapi/Response.php
+++ b/lib/classes/restapi/Response.php
@@ -123,41 +123,25 @@ class Response implements \ArrayAccess
 
     // array access methods for headers
 
-    /**
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->headers[$offset]);
     }
 
     /**
      * @param $offset
-     * @return mixed
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[\ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return @$this->headers[$offset];
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->headers[$offset] = $value;
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         unset($this->headers[$offset]);
     }
diff --git a/lib/classes/sidebar/AttributesArrayAccessTrait.php b/lib/classes/sidebar/AttributesArrayAccessTrait.php
index 7bea8348f17..09fc03008f5 100644
--- a/lib/classes/sidebar/AttributesArrayAccessTrait.php
+++ b/lib/classes/sidebar/AttributesArrayAccessTrait.php
@@ -3,41 +3,25 @@ trait AttributesArrayAccessTrait
 {
     public $attributes = [];
 
-    /**
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return isset($this->attributes[$offset]);
     }
 
     /**
-     * @param $offset
-     * @return mixed
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
+     * @param string $offset
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->attributes[$offset];
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->attributes[$offset] = $value;
     }
 
-    /**
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
-     */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         unset($this->attributes[$offset]);
     }
diff --git a/lib/filesystem/StandardFile.php b/lib/filesystem/StandardFile.php
index e051871e8a4..9d2d35c93e3 100644
--- a/lib/filesystem/StandardFile.php
+++ b/lib/filesystem/StandardFile.php
@@ -112,46 +112,33 @@ class StandardFile implements FileType, ArrayAccess, StandardFileInterface
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return $this->__isset($offset);
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->__get($offset);
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->__set($offset, $value);
     }
 
     /**
      * ArrayAccess: unset the value at the given offset (not applicable)
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
-
     }
 
     /**
diff --git a/lib/filesystem/UnknownFileType.php b/lib/filesystem/UnknownFileType.php
index bfd00ba119f..33d6c53bed7 100644
--- a/lib/filesystem/UnknownFileType.php
+++ b/lib/filesystem/UnknownFileType.php
@@ -51,46 +51,33 @@ class UnknownFileType implements FileType, ArrayAccess
 
     /**
      * ArrayAccess: Check whether the given offset exists.
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return $this->__isset($offset);
     }
 
     /**
      * ArrayAccess: Get the value at the given offset.
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->__get($offset);
     }
 
     /**
      * ArrayAccess: Set the value at the given offset.
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->__set($offset, $value);
     }
 
     /**
      * ArrayAccess: unset the value at the given offset (not applicable)
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
-
     }
     /**
      * @inheritDoc
diff --git a/lib/models/DataField.class.php b/lib/models/DataField.class.php
index 2d745a9de6b..8a0bdb68e40 100644
--- a/lib/models/DataField.class.php
+++ b/lib/models/DataField.class.php
@@ -256,11 +256,8 @@ class DataField extends SimpleORMap implements PrivacyObject
      * Specialized count method that returns the number of concrete entries.
      *
      * @return int number of entries
-     *
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return DatafieldEntryModel::countBySQL('datafield_id = ?', [$this->id]);
     }
diff --git a/lib/models/SimpleCollection.class.php b/lib/models/SimpleCollection.class.php
index 4d776824003..6acc10d4d40 100644
--- a/lib/models/SimpleCollection.class.php
+++ b/lib/models/SimpleCollection.class.php
@@ -299,12 +299,9 @@ class SimpleCollection extends StudipArrayObject
      * @param mixed $newval
      *
      * @see ArrayObject::offsetSet()
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($index, $newval)
+
+    public function offsetSet($index, $newval): void
     {
         if (is_numeric($index)) {
             $index = (int) $index;
@@ -318,11 +315,8 @@ class SimpleCollection extends StudipArrayObject
      *
      * @see ArrayObject::offsetUnset()
      * @throws InvalidArgumentException
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($index)
+    public function offsetUnset($index): void
     {
         if ($this->offsetExists($index)) {
             $this->deleted[] = $this->offsetGet($index);
diff --git a/lib/models/SimpleORMap.class.php b/lib/models/SimpleORMap.class.php
index 2013db4aa95..f86ec6f54ed 100644
--- a/lib/models/SimpleORMap.class.php
+++ b/lib/models/SimpleORMap.class.php
@@ -1638,16 +1638,13 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
             return false;
         }
     }
+
     /**
      * ArrayAccess: Check whether the given offset exists.
      *
      * @param string $offset
-     * @return bool
-     *
-     * @todo Add bool return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         return $this->__isset($offset);
     }
@@ -1659,11 +1656,8 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
      * @throws BadMethodCallException if getter for additional field could not be found
      * @param string $offset the column or additional field
      * @return null|string|SimpleORMapCollection
-     *
-     * @todo Add mixed return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         return $this->getValue($offset);
     }
@@ -1675,49 +1669,34 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
      * @throws BadMethodCallException if setter for additional field could not be found
      * @param string $offset
      * @param mixed $value
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->setValue($offset, $value);
     }
+
     /**
      * ArrayAccess: unset the value at the given offset (not applicable)
      *
      * @param string $offset
-     * @return void
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
 
     }
+
     /**
      * IteratorAggregate
-     *
-     * @return ArrayIterator
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): ArrayIterator
     {
         return new ArrayIterator($this->toArray());
     }
+
     /**
      * Countable
-     *
-     * @return int
-     *
-     * @todo Add int return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->known_slots()) - count($this->relations);
     }
diff --git a/lib/models/SimpleORMapCollection.class.php b/lib/models/SimpleORMapCollection.class.php
index f06ee178e46..7debb80eaad 100644
--- a/lib/models/SimpleORMapCollection.class.php
+++ b/lib/models/SimpleORMapCollection.class.php
@@ -92,11 +92,8 @@ class SimpleORMapCollection extends SimpleCollection
      *
      * @see ArrayObject::offsetSet()
      * @throws InvalidArgumentException if the given model does not fit (wrong type or id)
-     *
-     * @todo Add void return type when Stud.IP requires PHP8 minimal
      */
-    #[ReturnTypeWillChange]
-    public function offsetSet($index, $newval)
+    public function offsetSet($index, $newval): void
     {
         if (!is_null($index)) {
             $index = (int)$index;
diff --git a/lib/navigation/Navigation.php b/lib/navigation/Navigation.php
index 3c02e86b317..af4355b02eb 100644
--- a/lib/navigation/Navigation.php
+++ b/lib/navigation/Navigation.php
@@ -562,12 +562,9 @@ class Navigation implements IteratorAggregate
     }
 
     /**
-     * IteratorAggregate: Create interator for request parameters.
-     *
-     * @todo Add Traversable return type when Stud.IP requires PHP8 minimal
+     * IteratorAggregate: Create iterator for request parameters.
      */
-    #[\ReturnTypeWillChange]
-    public function getIterator()
+    public function getIterator(): Traversable
     {
         return new ArrayIterator($this->getSubNavigation());
     }
diff --git a/phpstan-php8.neon.dist b/phpstan-php8.neon.dist
deleted file mode 100644
index ed3baef47f6..00000000000
--- a/phpstan-php8.neon.dist
+++ /dev/null
@@ -1,26 +0,0 @@
-parameters:
-    level: 0
-    phpVersion: 80000 # PHP 8.0
-    paths:
-        - app/controllers
-        - app/routes
-        - lib
-        - tests/functional
-        - tests/jsonapi
-        - tests/unit
-    scanFiles:
-        - composer/phpxmlrpc/phpxmlrpc/lib/xmlrpc.inc
-    scanDirectories:
-        - app/controllers
-        - lib
-        - vendor
-    excludePaths:
-        - lib/classes/ZipArchiveLegacyTrait.php
-        - lib/elearning/studip_referrer.php
-        - lib/soap/StudipSoapClient_PHP5.class.php
-    tmpDir: .caches
-    earlyTerminatingMethodCalls:
-        RESTAPI\RouteMap:
-            - error
-            - halt
-            - notFound
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 17ff7c69f4c..531053a4b97 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -1,6 +1,6 @@
 parameters:
     level: 0
-    phpVersion: 70400 # PHP 7.4
+    phpVersion: 80100 # PHP 8.1
     paths:
         - app/controllers
         - app/routes
-- 
GitLab