diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f4da20891502a3992abf2981d8f6c46e33868ab6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+tools/
+phpstan.neon
+.phpunit.result.cache
+phpunit.xml
\ No newline at end of file
diff --git a/.phive/phars.xml b/.phive/phars.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a1315a09b4adad780a9c5e52f74835c708c5c7d5
--- /dev/null
+++ b/.phive/phars.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phive xmlns="https://phar.io/phive">
+  <phar name="phpstan" version="^1.10.67" installed="1.10.67" location="./tools/phpstan" copy="false"/>
+</phive>
diff --git a/composer.json b/composer.json
index 406454cd68937afa5792659b62ba9b05873f9599..2aa0dfee51332f1754035597fa8dd17f207c3196 100644
--- a/composer.json
+++ b/composer.json
@@ -1,30 +1,30 @@
 {
-    "name": "quiqqer\/faq",
-    "type": "quiqqer-module",
-    "description": "With the FAQ page types it is easy to create FAQs for your users.",
-    "license": [
-        "PCSG QL-1.0",
-        "CC BY-NC-SA 4.0"
-    ],
-    "authors": [
-        {
-            "name": "Henning Leutz",
-            "email": "leutz@pcsg.de",
-            "homepage": "http:\/\/www.pcsg.de",
-            "role": "Developer"
-        }
-    ],
-    "support": {
-        "email": "support@pcsg.de",
-        "url": "http:\/\/www.pcsg.de"
-    },
-    "require": {
-        "php": ">=5.3",
-        "quiqqer\/quiqqer": "*@dev"
-    },
-    "autoload": {
-        "psr-4": {
-            "QUI\\FAQ\\": "src\/QUI\/FAQ\/"
-        }
+  "name": "quiqqer/faq",
+  "type": "quiqqer-module",
+  "description": "With the FAQ page types it is easy to create FAQs for your users.",
+  "license": [
+    "PCSG QL-1.0",
+    "CC BY-NC-SA 4.0"
+  ],
+  "authors": [
+    {
+      "name": "Henning Leutz",
+      "email": "leutz@pcsg.de",
+      "homepage": "https://www.pcsg.de",
+      "role": "Developer"
     }
+  ],
+  "support": {
+    "email": "support@pcsg.de",
+    "url": "https://www.pcsg.de"
+  },
+  "require": {
+    "php": "^8.1",
+    "quiqqer/core": "^2"
+  },
+  "autoload": {
+    "psr-4": {
+      "QUI\\FAQ\\": "src/QUI/FAQ/"
+    }
+  }
 }
\ No newline at end of file
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/phpstan.dist.neon b/phpstan.dist.neon
new file mode 100644
index 0000000000000000000000000000000000000000..e38c605eb308007e25589c067c241162442e615e
--- /dev/null
+++ b/phpstan.dist.neon
@@ -0,0 +1,10 @@
+includes:
+    - phpstan-baseline.neon
+
+parameters:
+    level: 1
+    paths:
+        - src
+        - types
+    bootstrapFiles:
+        - tests/phpstan-bootstrap.php
\ No newline at end of file
diff --git a/src/QUI/FAQ/Controls/Accordion.php b/src/QUI/FAQ/Controls/Accordion.php
index fa00c221d7880c82cb702d8e45276df1af17c3e1..72c2255f900e475ee2a72bcb41f81bb49fe64553 100644
--- a/src/QUI/FAQ/Controls/Accordion.php
+++ b/src/QUI/FAQ/Controls/Accordion.php
@@ -7,8 +7,12 @@
 namespace QUI\FAQ\Controls;
 
 use QUI;
+use QUI\Exception;
+use QUI\Projects\Site;
 use QUI\Projects\Site\Utils;
 
+use function boolval;
+
 /**
  * Class Listing
  *
@@ -22,27 +26,27 @@ class Accordion extends QUI\Control
      *
      * @param array $attributes
      */
-    public function __construct($attributes = [])
+    public function __construct(array $attributes = [])
     {
         // default options
         $this->setAttributes([
-            'class'                => 'quiqqer-faqAccordion',
-            'order'                => 'order_field',
-            'stayOpen'             => true, // if true make accordion items stay open when another item is opened
-            'openFirst'            => true, // the first entry is initially opened
-            'listMaxWidth'         => 0, // positive numbers only, 0 disabled this option.
-            'max'                  => 10, // max entries
-            'parentSite'           => null,
-            'siteType'             => 'quiqqer/faq:types/entry',
-            'showMoreButton'       => false,
-            'moreSite'             => '',
+            'class' => 'quiqqer-faqAccordion',
+            'order' => 'order_field',
+            'stayOpen' => true, // if true make accordion items stay open when another item is opened
+            'openFirst' => true, // the first entry is initially opened
+            'listMaxWidth' => 0, // positive numbers only, 0 disabled this option.
+            'max' => 10, // max entries
+            'parentSite' => null,
+            'siteType' => 'quiqqer/faq:types/entry',
+            'showMoreButton' => false,
+            'moreSite' => '',
             'useFaqStructuredData' => false
         ]);
 
         parent::__construct($attributes);
 
         $this->addCSSFile(
-            dirname(__FILE__).'/Accordion.css'
+            dirname(__FILE__) . '/Accordion.css'
         );
 
         $this->setAttribute('cacheable', 0);
@@ -53,18 +57,19 @@ class Accordion extends QUI\Control
      * Can be overwritten
      *
      * @return String
+     * @throws Exception
      */
-    public function getBody()
+    public function getBody(): string
     {
         $FAQParentSite = null;
-        $Engine        = QUI::getTemplateManager()->getEngine();
+        $Engine = QUI::getTemplateManager()->getEngine();
 
         if ($this->getAttribute('parentSite')) {
             try {
-                if ($this->getAttribute('parentSite') instanceof \QUI\Projects\Site) {
+                if ($this->getAttribute('parentSite') instanceof Site) {
                     $FAQParentSite = $this->getAttribute('parentSite');
                 } else {
-                    $FAQParentSite = \QUI\Projects\Site\Utils::getSiteByLink($this->getAttribute('parentSite'));
+                    $FAQParentSite = Utils::getSiteByLink($this->getAttribute('parentSite'));
                 }
             } catch (QUI\Exception $Exception) {
                 QUI\System\Log::addInfo($Exception->getMessage());
@@ -76,7 +81,7 @@ class Accordion extends QUI\Control
         $faqSites = $FAQParentSite->getChildren([
             'where' => [
                 'active' => 1,
-                'type'   => $this->getAttribute('siteType'),
+                'type' => $this->getAttribute('siteType'),
             ],
             'limit' => $this->getAttribute('max'),
             'order' => $this->getAttribute('order')
@@ -84,12 +89,12 @@ class Accordion extends QUI\Control
 
         // show "more faq" link
         $showMoreButton = $this->getAttribute('showMoreButton');
-        $MoreSite       = $FAQParentSite;
+        $MoreSite = $FAQParentSite;
 
         if ($showMoreButton || $this->getAttribute('moreSite')) {
             if ($this->getAttribute('moreSite')) {
                 try {
-                    $MoreSite       = \QUI\Projects\Site\Utils::getSiteByLink($this->getAttribute('moreSite'));
+                    $MoreSite = Utils::getSiteByLink($this->getAttribute('moreSite'));
                     $showMoreButton = true;
                 } catch (QUI\Exception $Exception) {
                     QUI\System\Log::addInfo($Exception->getMessage());
@@ -99,7 +104,7 @@ class Accordion extends QUI\Control
                 $countFaqEntries = $FAQParentSite->getChildren([
                     'where' => [
                         'active' => 1,
-                        'type'   => $this->getAttribute('siteType'),
+                        'type' => $this->getAttribute('siteType'),
                     ],
                     'count' => 1
                 ]);
@@ -113,21 +118,21 @@ class Accordion extends QUI\Control
         $entries = [];
 
         foreach ($faqSites as $FaqSite) {
-            $short   = $FaqSite->getAttribute('short');
+            $short = $FaqSite->getAttribute('short');
             $content = $FaqSite->getAttribute('content');
 
             if ($short) {
-                $short = '<div class="quiqqer-faqAccordion-item-content-pageShort text-muted">'.$short.'</div>';
+                $short = '<div class="quiqqer-faqAccordion-item-content-pageShort text-muted">' . $short . '</div>';
             }
 
             if ($content) {
-                $content = '<div class="quiqqer-faqAccordion-item-content-pageContent">'.$content.'</div>';
+                $content = '<div class="quiqqer-faqAccordion-item-content-pageContent">' . $content . '</div>';
             }
 
-            $entryContent = $short.$content;
+            $entryContent = $short . $content;
 
             $entry = [
-                'entryTitle'   => $FaqSite->getAttribute('title'),
+                'entryTitle' => $FaqSite->getAttribute('title'),
                 'entryContent' => $entryContent,
             ];
 
@@ -135,22 +140,22 @@ class Accordion extends QUI\Control
         }
 
         $Accordion = new QUI\Bricks\Controls\Accordion([
-            'stayOpen'             => \boolval($this->getAttribute('stayOpen')),
-            'openFirst'            => $this->getAttribute('openFirst'),
-            'listMaxWidth'         => $this->getAttribute('listMaxWidth'),
-            'entries'              => $entries,
+            'stayOpen' => boolval($this->getAttribute('stayOpen')),
+            'openFirst' => $this->getAttribute('openFirst'),
+            'listMaxWidth' => $this->getAttribute('listMaxWidth'),
+            'entries' => $entries,
             'useFaqStructuredData' => $this->getAttribute('useFaqStructuredData'),
         ]);
 
         $this->addCSSFiles($Accordion->getCSSFiles());
 
         $Engine->assign([
-            'this'           => $this,
-            'Accordion'      => $Accordion,
+            'this' => $this,
+            'Accordion' => $Accordion,
             'showMoreButton' => $showMoreButton,
-            'MoreSite'       => $MoreSite
+            'MoreSite' => $MoreSite
         ]);
 
-        return $Engine->fetch(dirname(__FILE__).'/Accordion.html');
+        return $Engine->fetch(dirname(__FILE__) . '/Accordion.html');
     }
 }
diff --git a/src/QUI/FAQ/EventsHandler.php b/src/QUI/FAQ/EventsHandler.php
index 545bed43bd07aa85813e175c741e79fa47d70bf7..2576e301cf1f80d4d7fdc68b4c1594986595c399 100644
--- a/src/QUI/FAQ/EventsHandler.php
+++ b/src/QUI/FAQ/EventsHandler.php
@@ -6,6 +6,8 @@
 
 namespace QUI\FAQ;
 
+use QUI\Exception;
+use QUI\Interfaces\Projects\Site;
 use QUI\Projects\Site\Edit;
 
 /**
@@ -19,20 +21,22 @@ class EventsHandler
      * event on child create
      *
      * @param integer $newId
-     * @param \QUI\Projects\Site\Edit $Parent
+     * @param Site $Parent
+     * @throws Exception
      */
-    public static function onChildCreate($newId, $Parent)
+    public static function onChildCreate(int $newId, Site $Parent): void
     {
         $type = $Parent->getAttribute('type');
 
-        if ($type != 'quiqqer/faq:types/list'
+        if (
+            $type != 'quiqqer/faq:types/list'
             && $type != 'quiqqer/faq:types/category'
         ) {
             return;
         }
 
         $Project = $Parent->getProject();
-        $Site    = new Edit($Project, $newId);
+        $Site = new Edit($Project, $newId);
 
         if ($type == 'quiqqer/faq:types/list') {
             $Site->setAttribute('type', 'quiqqer/faq:types/category');
diff --git a/tests/phpstan-bootstrap.php b/tests/phpstan-bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..b61ff4b8300a965e0f46025ba64745a22b118e74
--- /dev/null
+++ b/tests/phpstan-bootstrap.php
@@ -0,0 +1,13 @@
+<?php
+
+if (!defined('QUIQQER_SYSTEM')) {
+    define('QUIQQER_SYSTEM', true);
+}
+
+if (!defined('QUIQQER_AJAX')) {
+    define('QUIQQER_AJAX', true);
+}
+
+putenv("QUIQQER_OTHER_AUTOLOADERS=KEEP");
+
+require_once __DIR__ . '/../../../../bootstrap.php';
diff --git a/types/category.php b/types/category.php
index c87fd8dfd7e5b0b31f073a0239debfe33e61aa2c..0b7884c6897bd97b79cd4bf8bec02867b42f2f36 100644
--- a/types/category.php
+++ b/types/category.php
@@ -1,5 +1,14 @@
 <?php
 
+/**
+ * This file contains the category site type
+ *
+ * @var QUI\Projects\Project $Project
+ * @var QUI\Projects\Site $Site
+ * @var QUI\Interfaces\Template\EngineInterface $Engine
+ * @var QUI\Template $Template
+ **/
+
 $entries = $Site->getChildren([
     'type' => 'quiqqer/faq:types/entry'
 ]);
diff --git a/types/entry.php b/types/entry.php
index 03332611291deb4e62c3a761bb0c65ced53b5668..2dba676f22ec508ab12288a62afae6f1dc93a88c 100644
--- a/types/entry.php
+++ b/types/entry.php
@@ -1,13 +1,19 @@
 <?php
 
 /**
- * FAQ Entry
- */
+ * This file contains the faq entry site type
+ *
+ * @var QUI\Projects\Project $Project
+ * @var QUI\Projects\Site $Site
+ * @var QUI\Interfaces\Template\EngineInterface $Engine
+ * @var QUI\Template $Template
+ **/
 
-$Parent     = $Site->getParent();
+$Parent = $Site->getParent();
 $parentType = $Parent->getAttribute('type');
 
-if ($parentType == 'quiqqer/faq:types/list'
+if (
+    $parentType == 'quiqqer/faq:types/list'
     || $parentType == 'quiqqer/faq:types/category'
 ) {
     QUI::getRewrite()->showErrorHeader(
diff --git a/types/list.php b/types/list.php
index 7c418125dcf1fee783e71492c9a39efa231d3421..7bdfc37d4d54c5195f6c50d5f43961c3d580f46a 100644
--- a/types/list.php
+++ b/types/list.php
@@ -1,9 +1,18 @@
 <?php
 
-$categories = $Site->getChildren(array(
+/**
+ * This file contains the faq list site type
+ *
+ * @var QUI\Projects\Project $Project
+ * @var QUI\Projects\Site $Site
+ * @var QUI\Interfaces\Template\EngineInterface $Engine
+ * @var QUI\Template $Template
+ **/
+
+$categories = $Site->getChildren([
     'type' => 'quiqqer/faq:types/category'
-));
+]);
 
-$Engine->assign(array(
+$Engine->assign([
     'categories' => $categories
-));
+]);