From 0d95625c2ab0eabe98e724ab79be0087093cc35b Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Wed, 4 May 2022 14:18:41 +0000
Subject: [PATCH] fix for BIESt #957

Merge request studip/studip!554
---
 app/controllers/news.php                      |  4 +-
 app/controllers/plugin_controller.php         |  4 ++
 app/controllers/studip_controller.php         |  4 +-
 app/views/calendar/contentbox/display.php     |  4 +-
 app/views/news/display.php                    |  1 -
 lib/bootstrap.php                             |  6 +--
 lib/calendar/CalendarColumn.class.php         |  4 +-
 lib/classes/Assets.class.php                  |  2 +-
 lib/classes/Avatar.class.php                  |  2 +-
 lib/classes/Log.php                           |  6 +--
 lib/classes/NotificationCenter.class.php      |  9 +++--
 lib/classes/PageLayout.php                    |  2 +-
 lib/classes/RangeConfig.class.php             |  4 +-
 lib/classes/Request.class.php                 |  2 +-
 lib/classes/SemBrowse.class.php               |  2 +-
 lib/classes/SkipLinks.php                     | 16 ++++++++
 lib/classes/Smiley.php                        |  2 +-
 lib/classes/StudipPDO.class.php               |  2 +-
 lib/classes/StudipPDOStatement.php            |  2 +
 lib/classes/URLHelper.php                     | 10 ++++-
 lib/classes/Widget.php                        |  2 +-
 lib/classes/WidgetContainer.php               | 16 ++++----
 .../calendar/CalendarScheduleModel.php        |  2 +-
 lib/classes/helpbar/Helpbar.php               |  4 +-
 lib/classes/sidebar/LinkElement.php           |  2 +-
 lib/classes/sidebar/SidebarWidget.php         |  2 +-
 lib/functions.php                             |  7 ++--
 lib/include/html_end.inc.php                  |  2 +-
 lib/migrations/Migrator.php                   | 12 +++---
 lib/models/HelpTour.class.php                 |  5 ++-
 lib/models/SimpleORMap.class.php              | 40 ++++++++++---------
 lib/models/StudipNews.class.php               |  3 +-
 lib/navigation/BrowseNavigation.php           |  1 +
 lib/navigation/ContentsNavigation.php         |  2 +-
 lib/navigation/Navigation.php                 |  4 +-
 lib/navigation/StartNavigation.php            |  4 +-
 lib/object.inc.php                            |  2 +-
 lib/phplib/Seminar_Auth.class.php             | 17 +++++---
 lib/phplib/Seminar_Perm.class.php             | 38 +++++++++++-------
 lib/phplib/Seminar_Session.class.php          |  2 +-
 lib/phplib/Seminar_User.class.php             |  3 +-
 lib/phplib/page_open.php                      |  8 ++--
 lib/plugins/engine/PluginManager.class.php    |  4 +-
 lib/seminar_open.php                          |  6 +--
 .../EvaluationsWidget/EvaluationsWidget.php   |  2 +-
 templates/debug/db-log.php                    |  2 +-
 templates/footer.php                          |  4 +-
 templates/header-navigation-item.php          |  4 +-
 templates/header.php                          |  2 +-
 templates/index_nobody.php                    |  8 ++--
 templates/layouts/base.php                    | 12 +++---
 templates/sidebar/list-widget.php             | 12 +++---
 templates/sidebar/widget-layout.php           |  7 ++--
 53 files changed, 194 insertions(+), 135 deletions(-)

diff --git a/app/controllers/news.php b/app/controllers/news.php
index 6ce922e2e4c..4244b883167 100644
--- a/app/controllers/news.php
+++ b/app/controllers/news.php
@@ -114,7 +114,7 @@ class NewsController extends StudipController
                     $news->deleteRange($range);
                     $news->store();
                 } else {
-                    $this->question = (string) QuestionBox::create(
+                    PageLayout::postQuestion(
                         _('Ankündigung wirklich aus diesem Bereich entfernen?'),
                         URLHelper::getURL('', ['remove_news' => $news_id, 'news_range' => $range, 'confirm' => true])
                     );
@@ -129,7 +129,7 @@ class NewsController extends StudipController
                 if (Request::get('confirm')) {
                     $news->delete();
                 } else {
-                    $this->question = (string) QuestionBox::create(
+                    PageLayout::postQuestion(
                         _('Ankündigung wirklich löschen?'),
                         URLHelper::getURL('', ['delete_news' => $news_id, 'confirm' => true])
                     );
diff --git a/app/controllers/plugin_controller.php b/app/controllers/plugin_controller.php
index 7710bff2376..445f22e2b3e 100644
--- a/app/controllers/plugin_controller.php
+++ b/app/controllers/plugin_controller.php
@@ -14,8 +14,12 @@ class PluginController extends StudipController
     {
         parent::__construct($dispatcher);
 
+        if (!isset($dispatcher->current_plugin)) {
+            throw new Exception('Plugin missing for plugin controller!');
+        }
         $this->plugin = $dispatcher->current_plugin;
 
+
         if ($this->plugin && $this->plugin->hasTranslation()) {
             // Localization
             $this->_ = function ($string) {
diff --git a/app/controllers/studip_controller.php b/app/controllers/studip_controller.php
index fd52034cd8f..deeacdb9760 100644
--- a/app/controllers/studip_controller.php
+++ b/app/controllers/studip_controller.php
@@ -293,7 +293,9 @@ abstract class StudipController extends Trails_Controller
         $to = implode('/', $args);
 
         //preserve fragment
-        [$to, $fragment] = explode('#', $to);
+        $to_parts = explode('#', $to);
+        $to = $to_parts[0];
+        $fragment = $to_parts[1] ?? '';
 
         $url = parent::url_for($to);
 
diff --git a/app/views/calendar/contentbox/display.php b/app/views/calendar/contentbox/display.php
index 39927530cda..6791670a1ca 100644
--- a/app/views/calendar/contentbox/display.php
+++ b/app/views/calendar/contentbox/display.php
@@ -8,7 +8,7 @@
         <nav>
     <? if ($admin): ?>
         <? if ($isProfile): ?>
-        <a href="<?= URLHelper::getLink('dispatch.php/calendar/single/edit/' . $termin->id, ['source_page' => 'dispatch.php/profile']) ?>">
+        <a href="<?= URLHelper::getLink('dispatch.php/calendar/single/edit/', ['source_page' => 'dispatch.php/profile']) ?>">
             <?= Icon::create('add', 'clickable')->asImg(['class' => 'text-bottom']) ?>
         </a>
         <? else: ?>
@@ -34,4 +34,4 @@
     </section>
   <? endif; ?>
 </article>
-<? endif; ?>
\ No newline at end of file
+<? endif; ?>
diff --git a/app/views/news/display.php b/app/views/news/display.php
index 7ffd856fe9d..873a79c1e00 100644
--- a/app/views/news/display.php
+++ b/app/views/news/display.php
@@ -1,4 +1,3 @@
-<?= $question ?>
 <? if ($perm || $news): ?>
 <article class="studip">
     <header>
diff --git a/lib/bootstrap.php b/lib/bootstrap.php
index 608f929805d..20c1be57da9 100644
--- a/lib/bootstrap.php
+++ b/lib/bootstrap.php
@@ -50,11 +50,11 @@ if (isset($_SERVER['SERVER_NAME'])) {
             explode(':', $_SERVER['SERVER_NAME']);
     }
 
-    $ABSOLUTE_URI_STUDIP = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
+    $ABSOLUTE_URI_STUDIP = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
     $ABSOLUTE_URI_STUDIP .= '://'.$_SERVER['SERVER_NAME'];
 
-    if ($_SERVER['HTTPS'] == 'on' && $_SERVER['SERVER_PORT'] != 443 ||
-        $_SERVER['HTTPS'] != 'on' && $_SERVER['SERVER_PORT'] != 80) {
+    if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' && $_SERVER['SERVER_PORT'] != 443 ||
+        empty($SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] != 80) {
         $ABSOLUTE_URI_STUDIP .= ':'.$_SERVER['SERVER_PORT'];
     }
 
diff --git a/lib/calendar/CalendarColumn.class.php b/lib/calendar/CalendarColumn.class.php
index 2a0821f2cea..5e1b9099aa6 100644
--- a/lib/calendar/CalendarColumn.class.php
+++ b/lib/calendar/CalendarColumn.class.php
@@ -178,7 +178,7 @@ class CalendarColumn {
      */
     public function getGroupedEntries()
     {
-        if (!$this->sorted_entries) {
+        if (empty($this->sorted_entries)) {
             if ($this->isGrouped()) {
                 $this->sorted_entries = $this->sortAndGroupEntries();
             } else {
@@ -361,4 +361,4 @@ class CalendarColumn {
         $this->grouped = $grouped;
     }
 
-}
\ No newline at end of file
+}
diff --git a/lib/classes/Assets.class.php b/lib/classes/Assets.class.php
index 1d9c23f8b07..dd82073cac7 100644
--- a/lib/classes/Assets.class.php
+++ b/lib/classes/Assets.class.php
@@ -145,7 +145,7 @@ class Assets
 
         $parts = explode('/', $source);
 
-        $size = $opt['size'];
+        $size = $opt['size'] ?? null;
 
         $opt = Assets::parse_attributes($opt);
 
diff --git a/lib/classes/Avatar.class.php b/lib/classes/Avatar.class.php
index b355a8ac093..dab3f75ec3e 100644
--- a/lib/classes/Avatar.class.php
+++ b/lib/classes/Avatar.class.php
@@ -244,7 +244,7 @@ class Avatar {
             $opt['class'] = $this->getCssClass($size);
         }
 
-        if (is_string($opt['title']) && $opt['title'] !== html_entity_decode($opt['title'])) {
+        if (isset($opt['title']) && $opt['title'] !== html_entity_decode($opt['title'])) {
             // Decode already htmlready encoded titles (which were used until
             // all attributes were encoded inside this method)
             $opt['title'] = html_entity_decode($opt['title']);
diff --git a/lib/classes/Log.php b/lib/classes/Log.php
index 22c9f6cdc67..335572dc150 100644
--- a/lib/classes/Log.php
+++ b/lib/classes/Log.php
@@ -119,9 +119,7 @@ class Log
     public static function set($name = '', $log_handler = null)
     {
         $name = mb_strlen($name) ? $name : 0;
-        if (isset(self::$instances[$name])) {
-            $old = self::$instances[$name];
-        }
+        $old = self::$instances[$name] ?? null;
         self::$instances[$name] = new Log($log_handler);
         return $old;
     }
@@ -255,4 +253,4 @@ class Log
         }
         throw new BadMethodCallException('Unknown method called: ' . $name);
     }
-}
\ No newline at end of file
+}
diff --git a/lib/classes/NotificationCenter.class.php b/lib/classes/NotificationCenter.class.php
index dce878e0074..aaaa9e8f3f0 100644
--- a/lib/classes/NotificationCenter.class.php
+++ b/lib/classes/NotificationCenter.class.php
@@ -57,6 +57,8 @@ class NotificationCenter
             $event = '';
         }
 
+        $predicate = null;
+
         if ($object) {
             $predicate = is_callable($object)
                 ? $object
@@ -65,9 +67,10 @@ class NotificationCenter
                   };
         }
 
-        self::$observers[$event][] =
-            ['predicate' => $predicate ?: NULL,
-                  'observer'  => [$observer, $method]];
+        self::$observers[$event][] = [
+            'predicate' => $predicate,
+            'observer'  => [$observer, $method]
+        ];
     }
 
     /**
diff --git a/lib/classes/PageLayout.php b/lib/classes/PageLayout.php
index e40b22bfad1..a8f3ffac40c 100644
--- a/lib/classes/PageLayout.php
+++ b/lib/classes/PageLayout.php
@@ -463,7 +463,7 @@ class PageLayout
      */
     public static function isHeaderEnabled()
     {
-        return self::$display_header && !$GLOBALS['_NOHEADER'];
+        return self::$display_header && empty($GLOBALS['_NOHEADER']);
     }
 
     /**
diff --git a/lib/classes/RangeConfig.class.php b/lib/classes/RangeConfig.class.php
index c38466163c3..fc90434cf68 100644
--- a/lib/classes/RangeConfig.class.php
+++ b/lib/classes/RangeConfig.class.php
@@ -52,7 +52,7 @@ class RangeConfig extends Config
             $range_id = $range_id->getRangeId();
         }
 
-        if (static::$instances[$range_id] === null) {
+        if (!isset(static::$instances[$range_id])) {
             static::$instances[$range_id] = new static($range_id);
         }
         return static::$instances[$range_id];
@@ -121,7 +121,7 @@ class RangeConfig extends Config
             }
             while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
                 $this->data[$row['field']] = $this->convertFromDatabase(
-                    $this->metadata[$row['field']]['type'],
+                    $this->metadata[$row['field']]['type'] ?? 'string',
                     $row['value'],
                     $row['field']
                 );
diff --git a/lib/classes/Request.class.php b/lib/classes/Request.class.php
index 410a74fa0a8..71c593e58b7 100644
--- a/lib/classes/Request.class.php
+++ b/lib/classes/Request.class.php
@@ -114,7 +114,7 @@ class Request implements ArrayAccess, IteratorAggregate
     {
         $host = $_SERVER['SERVER_NAME'];
         $port = $_SERVER['SERVER_PORT'];
-        $ssl  = $_SERVER['HTTPS'] == 'on';
+        $ssl  = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
 
         if ($ssl && $port != 443 || !$ssl && $port != 80) {
             $host .= ':' . $port;
diff --git a/lib/classes/SemBrowse.class.php b/lib/classes/SemBrowse.class.php
index 1bc822bd477..82b683fbfa9 100644
--- a/lib/classes/SemBrowse.class.php
+++ b/lib/classes/SemBrowse.class.php
@@ -1168,7 +1168,7 @@ class SemBrowse {
         if (!$option['visible'] || $option['target'] != $target) {
             return null;
         }
-        if (!$option['url']) {
+        if (empty($option['url'])) {
             switch ($option_name) {
                 case 'courses':
                 case 'semtree':
diff --git a/lib/classes/SkipLinks.php b/lib/classes/SkipLinks.php
index c5738b2af6f..e2744b91723 100644
--- a/lib/classes/SkipLinks.php
+++ b/lib/classes/SkipLinks.php
@@ -101,4 +101,20 @@ class SkipLinks
         }
         return $GLOBALS['template_factory']->render('skiplinks', compact('navigation'));
     }
+
+    /**
+     * Checks if there is another link at the same position and if it is overwritable.
+     *
+     * @return boolean true if the link at the same position is overwritable
+     */
+    private static function checkOverwrite($link)
+    {
+        if (isset(self::$position[$link['position']])) {
+            return false;
+        }
+        if (empty($link['overwrite'])) {
+            self::$position[$link['position']] = true;
+        }
+        return true;
+    }
 }
diff --git a/lib/classes/Smiley.php b/lib/classes/Smiley.php
index 803a5f48429..8d37e4f225b 100644
--- a/lib/classes/Smiley.php
+++ b/lib/classes/Smiley.php
@@ -224,7 +224,7 @@ class Smiley
      */
     public static function getShort()
     {
-        if (class_exists('DBManager') && !$GLOBALS['SMILEY_NO_DB']) {
+        if (class_exists('DBManager') && empty($GLOBALS['SMILEY_NO_DB'])) {
             if (self::$shortnames === null) {
                 $query = "SELECT short_name, smiley_name FROM smiley WHERE short_name != ''";
                 self::$shortnames = DBManager::get()->query($query)->fetchGrouped(PDO::FETCH_COLUMN);
diff --git a/lib/classes/StudipPDO.class.php b/lib/classes/StudipPDO.class.php
index c73bb7e8e94..8e67c342931 100644
--- a/lib/classes/StudipPDO.class.php
+++ b/lib/classes/StudipPDO.class.php
@@ -43,7 +43,7 @@ class StudipPDO extends PDO
         // method that is executed on every call to the database)
         $this->query_count += 1;
 
-        if ($GLOBALS['DEBUG_ALL_DB_QUERIES']) {
+        if (!empty($GLOBALS['DEBUG_ALL_DB_QUERIES'])) {
             $trace = debug_backtrace();
 
             $classes = [];
diff --git a/lib/classes/StudipPDOStatement.php b/lib/classes/StudipPDOStatement.php
index 51972ed60c0..5aab1cc807e 100644
--- a/lib/classes/StudipPDOStatement.php
+++ b/lib/classes/StudipPDOStatement.php
@@ -118,6 +118,8 @@ class StudipPDOStatement implements IteratorAggregate
         }
 
         // emulate prepared statement if necessary
+        $emulate_prepare = false;
+
         foreach ($this->params as $key => $param) {
             if ($param['type'] === StudipPDO::PARAM_ARRAY ||
                 $param['type'] === StudipPDO::PARAM_COLUMN ||
diff --git a/lib/classes/URLHelper.php b/lib/classes/URLHelper.php
index a36cc10377f..ae83022dd9b 100644
--- a/lib/classes/URLHelper.php
+++ b/lib/classes/URLHelper.php
@@ -169,8 +169,14 @@ class URLHelper
     {
         $link_params = $ignore_registered_params ? [] : self::$params;
 
-        list($url, $fragment) = explode('#', $url);
-        list($url, $query)    = explode('?', $url);
+        // Separate the query and the fragment parts (if any) from the main part of the URL
+        if (strpos($url, '#') !== false) {
+            list($url, $fragment) = explode('#', $url);
+        }
+
+        if (strpos($url, '?') !== false) {
+            list($url, $query) = explode('?', $url);
+        }
 
         if ($url !== '') {
             $url = self::resolveURL($url);
diff --git a/lib/classes/Widget.php b/lib/classes/Widget.php
index 90f3d564efe..f2dd3f06029 100644
--- a/lib/classes/Widget.php
+++ b/lib/classes/Widget.php
@@ -231,7 +231,7 @@ class Widget
 
     public function __get($offset)
     {
-        return $this->template_variables[$offset];
+        return $this->template_variables[$offset] ?? null;
     }
 
     public function __set($offset, $value)
diff --git a/lib/classes/WidgetContainer.php b/lib/classes/WidgetContainer.php
index 5287305a1f0..1b0578eb323 100644
--- a/lib/classes/WidgetContainer.php
+++ b/lib/classes/WidgetContainer.php
@@ -24,12 +24,12 @@ abstract class WidgetContainer
     public static function Get()
     {
         $class = get_called_class();
-        if (static::$instances[$class] === null) {
+        if (!isset(static::$instances[$class])) {
             static::$instances[$class] = new static;
         }
         return static::$instances[$class];
     }
-    
+
     /**
      * Private constructor to ensure that the singleton Get() method is always
      * used.
@@ -39,12 +39,12 @@ abstract class WidgetContainer
     protected function __construct()
     {
     }
-    
+
     /**
      * Contains the widgets of the container
      */
     protected $widgets = [];
-    
+
     /**
      * Add a widget to the container.
      *
@@ -75,9 +75,9 @@ abstract class WidgetContainer
     public function insertWidget(Widget $widget, $before_index, $index = null)
     {
         $index = $index ?: $this->guessIndex($widget);
-        
+
         $inserted = false;
-        
+
         $widgets = [];
         foreach ($this->widgets as $idx => $wdgt) {
             if ($idx === $before_index) {
@@ -96,7 +96,7 @@ abstract class WidgetContainer
         }
 
         $this->widgets = $widgets;
-        
+
         return $widget;
     }
 
@@ -151,7 +151,7 @@ abstract class WidgetContainer
      *
      * @param String $index Index/name of the widget to remove.
      * @throws Exception if the specified position is invalid
-     */ 
+     */
     public function removeWidget($index)
     {
         if (!isset($this->widgets[$index])) {
diff --git a/lib/classes/calendar/CalendarScheduleModel.php b/lib/classes/calendar/CalendarScheduleModel.php
index 20f66c57a37..04c44b770db 100644
--- a/lib/classes/calendar/CalendarScheduleModel.php
+++ b/lib/classes/calendar/CalendarScheduleModel.php
@@ -789,7 +789,7 @@ class CalendarScheduleModel
 
         $view = new CalendarWeekView($entries, 'schedule');
 
-        $view->setHeight(40 + (20 * $schedule_settings['zoom']));
+        $view->setHeight(40 + (20 * ($schedule_settings['zoom'] ?? 0)));
         $view->setRange($schedule_settings['glb_start_time'], $schedule_settings['glb_end_time']);
         $view->setInsertFunction("function (entry, column, hour, end_hour) {
             STUDIP.Schedule.newEntry(entry, column, hour, end_hour)
diff --git a/lib/classes/helpbar/Helpbar.php b/lib/classes/helpbar/Helpbar.php
index d2161fa307b..e01ad56746a 100644
--- a/lib/classes/helpbar/Helpbar.php
+++ b/lib/classes/helpbar/Helpbar.php
@@ -31,9 +31,9 @@ class Helpbar extends WidgetContainer
         $route        = get_route();
         $help_content = HelpContent::getContentByRoute();
         foreach ($help_content as $row) {
-            $this->addPlainText($row['label'] ?: '',
+            $this->addPlainText('',
                                 $this->interpolate($row['content'], $this->variables),
-                                $row['icon'] ? Icon::create($row['icon'], 'info_alt') : null,
+                                null,
                                 URLHelper::getURL('dispatch.php/help_content/edit/'.$row['content_id'], ['from' => $route]),
                                 URLHelper::getURL('dispatch.php/help_content/delete/'.$row['content_id'], ['from' => $route]));
         }
diff --git a/lib/classes/sidebar/LinkElement.php b/lib/classes/sidebar/LinkElement.php
index b38a1453eab..8b20dbea8f7 100644
--- a/lib/classes/sidebar/LinkElement.php
+++ b/lib/classes/sidebar/LinkElement.php
@@ -151,7 +151,7 @@ class LinkElement extends WidgetElement implements ArrayAccess
      */
     public function addClass($class)
     {
-        $this->attributes['class'] = $this->attributes['class']
+        $this->attributes['class'] = isset($this->attributes['class'])
             ? $this->attributes['class'] . " " . $class
             : $class;
         return $this;
diff --git a/lib/classes/sidebar/SidebarWidget.php b/lib/classes/sidebar/SidebarWidget.php
index 026ca0cda70..00735aca4e7 100644
--- a/lib/classes/sidebar/SidebarWidget.php
+++ b/lib/classes/sidebar/SidebarWidget.php
@@ -91,7 +91,7 @@ class SidebarWidget extends Widget
      */
     public function render($variables = [])
     {
-        if ($this->id) {
+        if (!empty($this->id)) {
             $this->template_variables['id'] = $this->id;
         }
         return parent::render($variables);
diff --git a/lib/functions.php b/lib/functions.php
index 5d3d2bca50a..ae7307e2c7e 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -1007,7 +1007,7 @@ function format_help_url($keyword)
 {
     // all help urls need short language tag (de, en)
     $lang = 'de';
-    if ($_SESSION['_language']) {
+    if (!empty($_SESSION['_language'])) {
         [$lang] = explode('_', $_SESSION['_language']);
     }
 
@@ -1429,10 +1429,11 @@ function get_route($route = '')
         $trails = explode('dispatch.php/', $route);
         $dispatcher = new StudipDispatcher();
         $pieces = explode('/', $trails[1]);
+        $trail = '';
         foreach ($pieces as $index => $piece) {
             $trail .= ($trail ? '/' : '') . $piece;
             if ($dispatcher->file_exists($trail . '.php')) {
-                $route = 'dispatch.php/' . $trail . ($pieces[$index+1] ? '/' . $pieces[$index+1] : '');
+                $route = 'dispatch.php/' . $trail . (isset($pieces[$index+1]) ? '/' . $pieces[$index+1] : '');
             }
         }
     }
@@ -1461,7 +1462,7 @@ function match_route($requested_route, $current_route = '')
         return false;
     }
     // if no parameters given and base routes do match, return true
-    if (!$route_parts[1]) {
+    if (empty($route_parts[1])) {
         return true;
     }
     // extract vars and check if they are set accordingly
diff --git a/lib/include/html_end.inc.php b/lib/include/html_end.inc.php
index 24f935d28e1..3f41584d7e8 100644
--- a/lib/include/html_end.inc.php
+++ b/lib/include/html_end.inc.php
@@ -1,7 +1,7 @@
             </div>
         </div>
     </div>
-    <?= $GLOBALS['template_factory']->render('footer') ?>
+    <?= $GLOBALS['template_factory']->render('footer', ['header_template' => $header_template ?? null]) ?>
 <!-- Ende Page -->
 </div>
 
diff --git a/lib/migrations/Migrator.php b/lib/migrations/Migrator.php
index bcb1ddfd1a4..d0888f99cd9 100644
--- a/lib/migrations/Migrator.php
+++ b/lib/migrations/Migrator.php
@@ -250,13 +250,13 @@ class Migrator
     {
         $top_versions = $this->topVersion(true);
         $target_branch = $this->schema_version->getBranch();
-  
+
         if (is_array($target_version)) {
             return $target_version;
         }
-  
+
         $max_version = $target_branch ? $target_branch . '.' . $target_version : $target_version;
-  
+
         foreach ($top_versions as $branch => $version) {
             if ($branch == $target_branch) {
                 if (isset($target_version)) {
@@ -268,10 +268,10 @@ class Migrator
                 $top_versions[$branch] = 0;
             }
         }
-  
+
         return $top_versions;
     }
-  
+
     /**
      * Invoking this method will return a list of migrations with an index between
      * the current schema version (provided by the SchemaVersion object) and a
@@ -464,7 +464,7 @@ class Migrator
         $versions = [0];
         foreach (array_keys($this->migrationClasses()) as $version) {
             list($branch, $version) = $this->migrationBranchAndVersion($version);
-            $versions[$branch] = max($versions[$branch], $version);
+            $versions[$branch] = max($versions[$branch] ?? 0, $version);
         }
         return $all_branches ? $versions : $versions[$this->schema_version->getBranch()];
     }
diff --git a/lib/models/HelpTour.class.php b/lib/models/HelpTour.class.php
index d200ebaef1a..726cfa7697e 100644
--- a/lib/models/HelpTour.class.php
+++ b/lib/models/HelpTour.class.php
@@ -82,6 +82,8 @@ class HelpTour extends SimpleORMap
     public static function GetHelpbarTourData()
     {
         $visible_tours = [];
+        $active_tour_id = null;
+        $active_tour_step_nr = 0;
         $route = get_route();
         $tours = HelpTour::getToursByRoute($route);
         foreach($tours as $index => $tour) {
@@ -99,8 +101,9 @@ class HelpTour extends SimpleORMap
                 }
             }
         }
+
         //if there is an active tour, initialize it
-        if ($_SESSION['active_tour']['tour_id']
+        if (isset($_SESSION['active_tour']['tour_id'])
             && ($_SESSION['active_tour']['last_route'] === $route
                 || $_SESSION['active_tour']['next_route'] === $route))
         {
diff --git a/lib/models/SimpleORMap.class.php b/lib/models/SimpleORMap.class.php
index cc511381048..16eeadf711c 100644
--- a/lib/models/SimpleORMap.class.php
+++ b/lib/models/SimpleORMap.class.php
@@ -241,7 +241,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
         }
 
         foreach (['has_many', 'belongs_to', 'has_one', 'has_and_belongs_to_many'] as $type) {
-            if (is_array($config[$type])) {
+            if (isset($config[$type]) && is_array($config[$type])) {
                 foreach (array_keys($config[$type]) as $one) {
                     $config['relations'][$one] = null;
                 }
@@ -310,9 +310,9 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
 
         $config['known_slots'] = array_merge(
             array_keys($config['db_fields']),
-            array_keys($config['alias_fields'] ?: []),
-            array_keys($config['additional_fields'] ?: []),
-            array_keys($config['relations'] ?: [])
+            array_keys($config['alias_fields'] ?? []),
+            array_keys($config['additional_fields'] ?? []),
+            array_keys($config['relations'] ?? [])
         );
 
         foreach (array_map('strtolower', get_class_methods($class)) as $method) {
@@ -339,7 +339,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
             static::configure();
         }
 
-        return self::$config[static::class][$key];
+        return self::$config[static::class][$key] ?? null;
     }
 
     /**
@@ -827,6 +827,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
         $db_fields = static::config('db_fields');
         $name = strtolower($name);
         $class = get_called_class();
+        $order = '';
         $param_arr = [];
         $where = '';
         $where_param = is_array($arguments[0]) ? $arguments[0] : [$arguments[0]];
@@ -834,21 +835,21 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
         $field = substr($name, strlen($prefix) + 2);
         switch ($prefix) {
             case 'findone':
-                $order = $arguments[1];
+                $order = $arguments[1] ?? '';
                 $param_arr[0] =& $where;
                 $param_arr[1] = [$where_param];
                 $method = 'findonebysql';
                 break;
             case 'find':
             case 'findmany':
-                $order = $arguments[1];
+                $order = $arguments[1] ?? '';
                 $param_arr[0] =& $where;
                 $param_arr[1] = [$where_param];
                 $method = 'findbysql';
                 break;
             case 'findeach':
             case 'findeachmany':
-                $order = $arguments[2];
+                $order = $arguments[2] ?? '';
                 $param_arr[0] = $arguments[0];
                 $param_arr[1] =& $where;
                 $param_arr[2] = [$arguments[1]];
@@ -1024,10 +1025,10 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
      * @return array
      */
     protected function parseRelationOptions($type, $name, $options) {
-        if (!$options['class_name']) {
+        if (empty($options['class_name'])) {
             throw new Exception('Option class_name not set for relation ' . $name);
         }
-        if (!$options['assoc_foreign_key']) {
+        if (empty($options['assoc_foreign_key'])) {
             if ($type === 'has_many' || $type === 'has_one') {
                 $options['assoc_foreign_key'] = $this->pk[0];
             } else if ($type === 'belongs_to') {
@@ -1062,28 +1063,28 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
                 throw new Exception("For relation " . $name . " assoc_foreign_key must be a name of a column");
             }
         }
-        if (!$options['assoc_func']) {
+        if (empty($options['assoc_func'])) {
             if ($type !== 'has_and_belongs_to_many') {
                 $options['assoc_func'] = $options['assoc_foreign_key'] === 'id' ? 'find' : 'findBy' . $options['assoc_foreign_key'];
             } else {
                 $options['assoc_func'] = 'findThru';
             }
         }
-        if (!$options['foreign_key']) {
+        if (empty($options['foreign_key'])) {
             $options['foreign_key'] = 'id';
         }
-        if ($options['foreign_key'] instanceof Closure) {
+        if (isset($options['foreign_key']) && $options['foreign_key'] instanceof Closure) {
             $options['assoc_func_params_func'] = function($record) use ($name, $options) { return call_user_func($options['foreign_key'], $record, $name, $options);};
         } else {
             $options['assoc_func_params_func'] = function($record) use ($name, $options) { return $options['foreign_key'] === 'id' ? $record->getId() : $record->getValue($options['foreign_key']);};
         }
-        if ($options['assoc_foreign_key'] instanceof Closure) {
+        if (isset($options['assoc_foreign_key']) && $options['assoc_foreign_key'] instanceof Closure) {
             if ($type === 'belongs_to') {
                 $options['assoc_foreign_key_getter'] = function($record, $that) use ($name, $options) { return call_user_func($options['assoc_foreign_key'], $record, $name, $options, $that);};
             } else {
                 $options['assoc_foreign_key_setter'] = function($record, $params) use ($name, $options) { return call_user_func($options['assoc_foreign_key'], $record, $params, $name, $options);};
             }
-        } elseif ($options['assoc_foreign_key']) {
+        } elseif (!empty($options['assoc_foreign_key'])) {
             if ($type === 'belongs_to') {
                 $options['assoc_foreign_key_getter'] = function($record, $that) use ($name, $options) { return $record->getValue($options['assoc_foreign_key']);};
             } else {
@@ -1188,7 +1189,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
     function getId()
     {
         if (count($this->pk) == 1) {
-            return $this->content[$this->pk[0]];
+            return $this->content[$this->pk[0]] ?? null;
         } else {
             $id = [];
             foreach ($this->pk as $key) {
@@ -1758,7 +1759,7 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
         $where_query = null;
         $pk_not_set = [];
         foreach ($this->pk as $key) {
-            $pk = $this->content_db[$key] ?: $this->content[$key];
+            $pk = $this->content_db[$key] ?? $this->content[$key] ?? null;
             if (isset($pk)) {
                 $where_query[] = "`{$this->db_table}`.`{$key}` = "  . DBManager::get()->quote($pk);
             } else {
@@ -2134,7 +2135,10 @@ class SimpleORMap implements ArrayAccess, Countable, IteratorAggregate
             }
             $params = $options['assoc_func_params_func'];
             if ($options['type'] === 'has_many') {
-                $records = function($record) use ($to_call, $params, $options) {$p = (array)$params($record); return call_user_func_array($to_call, array_merge(count($p) ? $p : [null], [$options['order_by']]));};
+                $records = function($record) use ($to_call, $params, $options) {
+                    $p = (array)$params($record);
+                    return call_user_func_array($to_call, array_merge(count($p) ? $p : [null], [$options['order_by'] ?? '']));
+                };
                 $this->relations[$relation] = new SimpleORMapCollection($records, $options, $this);
             } elseif ($options['type'] === 'has_and_belongs_to_many') {
                 $records = function($record) use ($to_call, $params, $options) {$p = (array)$params($record); return call_user_func_array($to_call, array_merge(count($p) ? $p : [null], [$options]));};
diff --git a/lib/models/StudipNews.class.php b/lib/models/StudipNews.class.php
index 227561a125d..66f41090eea 100644
--- a/lib/models/StudipNews.class.php
+++ b/lib/models/StudipNews.class.php
@@ -94,7 +94,8 @@ class StudipNews extends SimpleORMap implements PrivacyObject
 
     public static function GetNewsByRange($range_id, $only_visible = false, $as_objects = false)
     {
-        if ($only_visible){
+        $clause = '';
+        if ($only_visible) {
             $clause = " AND date < UNIX_TIMESTAMP() AND (date + expire) > UNIX_TIMESTAMP() ";
         }
         $query = "SELECT news_id AS idx, news.*
diff --git a/lib/navigation/BrowseNavigation.php b/lib/navigation/BrowseNavigation.php
index e1788177ece..566e9d6a75b 100644
--- a/lib/navigation/BrowseNavigation.php
+++ b/lib/navigation/BrowseNavigation.php
@@ -24,6 +24,7 @@ class BrowseNavigation extends Navigation
     {
         global $user, $perm;
 
+        $courselink = null;
         // check if logged in
         if (is_object($user) && $user->id != 'nobody') {
             $coursetext = _('Veranstaltungen');
diff --git a/lib/navigation/ContentsNavigation.php b/lib/navigation/ContentsNavigation.php
index 767b86eed89..735d1d0d04e 100755
--- a/lib/navigation/ContentsNavigation.php
+++ b/lib/navigation/ContentsNavigation.php
@@ -117,7 +117,7 @@ class ContentsNavigation extends Navigation
                 $questionnaire->addSubNavigation('assign', $sub_nav);
             }
 
-            $eval = new Navigation(_('Evaluationen'), 'admin_evaluation.php', ['rangeID' => $auth->auth['uname']]);
+            $eval = new Navigation(_('Evaluationen'), 'admin_evaluation.php', ['rangeID' => $GLOBALS['user']->username]);
             $eval->setImage(Icon::create('test'));
             $eval->setDescription(_('Erstellen Sie komplexe Befragungen'));
             $this->addSubNavigation('evaluation', $eval);
diff --git a/lib/navigation/Navigation.php b/lib/navigation/Navigation.php
index 45b5bbf2cd0..ab4a8fe9736 100644
--- a/lib/navigation/Navigation.php
+++ b/lib/navigation/Navigation.php
@@ -120,9 +120,9 @@ class Navigation implements IteratorAggregate
             }
 
             $subnav = $node->getSubNavigation();
-            $node = $subnav[$name];
+            $node = $subnav[$name] ?? null;
 
-            if (!isset($node)) {
+            if (!$node) {
                 throw new InvalidArgumentException("navigation item '$path' not found");
             }
         }
diff --git a/lib/navigation/StartNavigation.php b/lib/navigation/StartNavigation.php
index 646ba4df5f2..973f7055680 100644
--- a/lib/navigation/StartNavigation.php
+++ b/lib/navigation/StartNavigation.php
@@ -30,6 +30,9 @@ class StartNavigation extends Navigation
     {
         parent::initItem();
 
+        $news = 0;
+        $vote = 0;
+
         if (mb_stripos($_SERVER['REQUEST_URI'], "web_migrate.php") === false && is_object($GLOBALS['user']) && $GLOBALS['user']->id != 'nobody') {
             if (WidgetHelper::hasWidget($GLOBALS['user']->id, 'News')) {
                 $news = StudipNews::CountUnread();
@@ -97,7 +100,6 @@ class StartNavigation extends Navigation
     public function initSubNavigation()
     {
         global $perm, $auth;
-        $username = $auth->auth['uname'];
 
         parent::initSubNavigation();
 
diff --git a/lib/object.inc.php b/lib/object.inc.php
index f7bcf903f70..c0c4e15653b 100644
--- a/lib/object.inc.php
+++ b/lib/object.inc.php
@@ -104,7 +104,7 @@ function object_get_visit($object_id, $plugin_id, $mode = "last", $open_object_i
         $cache[$object_id][$plugin_id][$user_id] = null;
     }
 
-    if ($cache[$object_id][$plugin_id][$user_id]) {
+    if (isset($cache[$object_id][$plugin_id][$user_id])) {
         return $mode == 'last'
              ? $cache[$object_id][$plugin_id][$user_id]['last_visitdate']
              : $cache[$object_id][$plugin_id][$user_id]['visitdate'];
diff --git a/lib/phplib/Seminar_Auth.class.php b/lib/phplib/Seminar_Auth.class.php
index db2828c1d49..dbd86b55b91 100644
--- a/lib/phplib/Seminar_Auth.class.php
+++ b/lib/phplib/Seminar_Auth.class.php
@@ -264,8 +264,13 @@ class Seminar_Auth
     {
         $cfg = Config::GetInstance();
         //check if the user got kicked meanwhile, or if user is locked out
-        if ($this->auth['uid'] && !in_array($this->auth['uid'], ['form', 'nobody'])) {
-            $user = $GLOBALS['user']->id == $this->auth['uid'] ? $GLOBALS['user'] : User::find($this->auth['uid']);
+        if (!empty($this->auth['uid']) && !in_array($this->auth['uid'], ['form', 'nobody'])) {
+            $user = null;
+            if (isset($GLOBALS['user']) && $GLOBALS['user']->id == $this->auth['uid']) {
+                $user = $GLOBALS['user'];
+            } else {
+                $user = User::find($this->auth['uid']);
+            }
             $exp_d = $user->username ? UserConfig::get($user->id)->EXPIRATION_DATE : 0;
             if (!$user->username || $user->locked || ($exp_d > 0 && $exp_d < time())) {
                 $this->unauth();
@@ -437,18 +442,18 @@ class Seminar_Auth
     {
         global $_language_path;
 
-        if ($GLOBALS['user']->id !== 'nobody') {
+        if (!isset($GLOBALS['user']) || $GLOBALS['user']->id !== 'nobody') {
             $GLOBALS['user'] = new Seminar_User('nobody');
             $GLOBALS['perm'] = new Seminar_Perm();
             $GLOBALS['auth'] = $this;
         }
 
-        $_SESSION['_language'] = $_SESSION['_language'] ?: get_accepted_languages();
+        if (empty($_SESSION['_language'])) {
+            $_SESSION['_language'] = get_accepted_languages();
+        }
 
         // init of output via I18N
         $_language_path = init_i18n($_SESSION['_language']);
         include 'config.inc.php';
-
-
     }
 }
diff --git a/lib/phplib/Seminar_Perm.class.php b/lib/phplib/Seminar_Perm.class.php
index e8469838e7f..c27d2ad5bb9 100644
--- a/lib/phplib/Seminar_Perm.class.php
+++ b/lib/phplib/Seminar_Perm.class.php
@@ -99,11 +99,14 @@ class Seminar_Perm
      */
     public function have_perm($perm, $user_id = false)
     {
-
-        $pageperm = $this->permissions[$perm];
-        $userperm = $this->permissions[$this->get_perm($user_id)];
-
-        return $pageperm <= $userperm;
+        $page_perm_value = $this->permissions[$perm] ?? 0;
+        $user_perm_value = $this->permissions[$this->get_perm($user_id)] ?? 0;
+        if ($user_perm_value) {
+            return $page_perm_value <= $user_perm_value;
+        } else {
+            //The user has no permissions at all.
+            return false;
+        }
     }
 
 
@@ -214,11 +217,14 @@ class Seminar_Perm
      */
     public function have_studip_perm($perm, $range_id, $user_id = false)
     {
-
-        $pageperm = $this->permissions[$perm];
-        $userperm = $this->permissions[$this->get_studip_perm($range_id, $user_id)];
-
-        return $pageperm <= $userperm;
+        $pageperm = $this->permissions[$perm] ?? 0;
+        $userperm = $this->permissions[$this->get_studip_perm($range_id, $user_id)] ?? 0;
+        if ($userperm) {
+            return $pageperm <= $userperm;
+        } else {
+            //The user has no permissions at all.
+            return false;
+        }
     }
 
     /**
@@ -293,10 +299,14 @@ class Seminar_Perm
     public function have_profile_perm($perm, $range_id, $user_id = false)
     {
 
-        $pageperm = $this->permissions[$perm];
-        $userperm = $this->permissions[$this->get_profile_perm($range_id, $user_id)];
-
-        return $pageperm <= $userperm;
+        $pageperm = $this->permissions[$perm] ?? 0;
+        $userperm = $this->permissions[$this->get_profile_perm($range_id, $user_id)] ?? 0;
+        if ($userperm) {
+            return $pageperm <= $userperm;
+        } else {
+            //The user has no permissions at all.
+            return false;
+        }
     }
 
     /**
diff --git a/lib/phplib/Seminar_Session.class.php b/lib/phplib/Seminar_Session.class.php
index 422419b0ddf..a5bc5927ab9 100644
--- a/lib/phplib/Seminar_Session.class.php
+++ b/lib/phplib/Seminar_Session.class.php
@@ -207,7 +207,7 @@ class Seminar_Session
             $this->that_class = 'CT_Cache';
         }
         $this->cookie_path = $this->cookie_path ?: $GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP'];
-        $this->cookie_secure = $_SERVER['HTTPS'] === 'on';
+        $this->cookie_secure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
         $this->name(get_class($this));
     }
 
diff --git a/lib/phplib/Seminar_User.class.php b/lib/phplib/Seminar_User.class.php
index 06ecf7c6916..c82d73a4d26 100644
--- a/lib/phplib/Seminar_User.class.php
+++ b/lib/phplib/Seminar_User.class.php
@@ -53,7 +53,8 @@ class Seminar_User
     {
         if ($this->id && $this->id != 'nobody') {
             if ($timestamp <= 0) {
-                if ((time() - $_SESSION['USER_LAST_LIFESIGN']) < 180) {
+                $current_user_last_lifesign = $_SESSION['USER_LAST_LIFESIGN'] ?? 0;
+                if (time() - $current_user_last_lifesign < 180) {
                     return 0;
                 }
                 $timestamp = time();
diff --git a/lib/phplib/page_open.php b/lib/phplib/page_open.php
index 5e638976ad6..699d50d7314 100644
--- a/lib/phplib/page_open.php
+++ b/lib/phplib/page_open.php
@@ -18,7 +18,7 @@ function page_open($feature) {
         # the auth feature depends on sess
         if (isset($feature["auth"])) {
 
-            if (is_object($_SESSION['auth'])) {
+            if (isset($_SESSION['auth'])) {
                 $_SESSION['auth'] = $_SESSION['auth']->check_feature($feature["auth"]);
             } else {
                 $_SESSION['auth'] = new $feature["auth"];
@@ -30,16 +30,14 @@ function page_open($feature) {
             # the perm feature depends on auth and sess
             if (isset($feature["perm"])) {
 
-                if (!is_object($GLOBALS['perm'])) {
+                if (!isset($GLOBALS['perm'])) {
                     $GLOBALS['perm'] = new $feature["perm"];
                 }
             }
 
             # the user feature depends on auth and sess
             if (isset($feature["user"])) {
-
-                if (!is_object($GLOBALS['user'])) {
-
+                if (!isset($GLOBALS['user'])) {
                     $GLOBALS['user'] = new $feature["user"]($GLOBALS['auth']->auth["uid"]);
                 }
             }
diff --git a/lib/plugins/engine/PluginManager.class.php b/lib/plugins/engine/PluginManager.class.php
index 1745e506ab5..ee5b43fdaca 100644
--- a/lib/plugins/engine/PluginManager.class.php
+++ b/lib/plugins/engine/PluginManager.class.php
@@ -222,7 +222,7 @@ class PluginManager
             $statement->execute([$userId]);
             $this->plugins_activated_cache[$userId] = $statement->fetchGrouped(PDO::FETCH_COLUMN);
         }
-        $state = $this->plugins_activated_cache[$userId][$pluginId];
+        $state = $this->plugins_activated_cache[$userId][$pluginId] ?? null;
         if ($state === null) {
             $activated = (bool) Config::get()->HOMEPAGEPLUGIN_DEFAULT_ACTIVATION;
         } else {
@@ -314,7 +314,7 @@ class PluginManager
      */
     public function isPluginsDisabled()
     {
-        return $_SESSION['plugins_disabled'];
+        return $_SESSION['plugins_disabled'] ?? false;
     }
 
     /**
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index abc134f93cb..c48ce07c6d3 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -75,7 +75,7 @@ $seminar_open_redirected = false;
 $user_did_login = false;
 
 // session init starts here
-if ($_SESSION['SessionStart'] == 0) {
+if (empty($_SESSION['SessionStart']) || $_SESSION['SessionStart'] == 0) {
     $_SESSION['SessionStart'] = time();
     $_SESSION['object_cache'] = [];
 
@@ -176,10 +176,10 @@ if (!Request::isXhr() && $perm->have_perm('root')) {
     }
 
     if (Request::option('stop-migration-nag')) {
-        $_SESSION['migation-check']['disabled'] = true;
+        $_SESSION['migration-check']['disabled'] = true;
     }
 
-    if (!$_SESSION['migation-check']['disabled']
+    if (!$_SESSION['migration-check']['disabled']
         && $_SESSION['migration-check']['count'] > 0
     ) {
         $info = sprintf(
diff --git a/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php b/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php
index c57b482a809..1dd7d3b0710 100644
--- a/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php
+++ b/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php
@@ -33,7 +33,7 @@ class EvaluationsWidget extends StudIPPlugin implements PortalPlugin
     {
         // include and show votes and tests
         if (Config::get()->VOTE_ENABLE) {
-            $controller = new PluginController(new StudipDispatcher());
+            $controller = new AuthenticatedController(new StudipDispatcher());
             $controller->suppress_empty_output = true;
 
             $response = $controller->relay('evaluation/display/studip')->body;
diff --git a/templates/debug/db-log.php b/templates/debug/db-log.php
index 141570e7abf..979729503a1 100644
--- a/templates/debug/db-log.php
+++ b/templates/debug/db-log.php
@@ -1,4 +1,4 @@
-<? if ($GLOBALS['DEBUG_ALL_DB_QUERIES']) : ?>
+<? if (!empty($GLOBALS['DEBUG_ALL_DB_QUERIES'])) : ?>
     <style>
     #all_db_queries td:first-child {
         border-left: 4px solid transparent;
diff --git a/templates/footer.php b/templates/footer.php
index 0ea313bd34c..0e046738b28 100644
--- a/templates/footer.php
+++ b/templates/footer.php
@@ -25,7 +25,7 @@
             /
             <?= sprintf('%.5f sec', microtime(true) - $GLOBALS['STUDIP_STARTUP_TIME']) ?>
         ]
-        <? if ($GLOBALS['DEBUG_ALL_DB_QUERIES']) : ?>
+        <? if (!empty($GLOBALS['DEBUG_ALL_DB_QUERIES'])) : ?>
             <a href="" onClick="jQuery('#all_db_queries').toggle(); return false;">
                 <?= Icon::create("code", "info_alt")->asImg(16, ['class' => "text-bottom"]) ?>
             </a>
@@ -41,7 +41,7 @@
             <li>
             <a
             <? if (is_internal_url($url = $nav->getURL())) : ?>
-                href="<?= URLHelper::getLink($url, $header_template->link_params) ?>"
+                href="<?= URLHelper::getLink($url, $link_params ?? null) ?>"
             <? else: ?>
                 href="<?= htmlReady($url) ?>" target="_blank" rel="noopener noreferrer"
             <? endif ?>
diff --git a/templates/header-navigation-item.php b/templates/header-navigation-item.php
index a163140efee..9fc875dfc9d 100644
--- a/templates/header-navigation-item.php
+++ b/templates/header-navigation-item.php
@@ -2,7 +2,9 @@
 $attributes = $nav->getLinkAttributes();
 
 $image_attributes = $nav->getImage()->getAttributes();
-$attributes['title'] = $image_attributes['title'];
+if (!empty($image_attributes['title'])) {
+    $attributes['title'] = $image_attributes['title'];
+}
 
 // Add badge number to link attributes
 if ($nav->getBadgeNumber()) {
diff --git a/templates/header.php b/templates/header.php
index 8f2992130ae..2f58da978d6 100644
--- a/templates/header.php
+++ b/templates/header.php
@@ -85,7 +85,7 @@ if (isset($_COOKIE['navigation-length'])) {
                             $alert = true;
                         }
                     } ?>
-                    <div id="notification_marker"<?= $alert ? ' class="alert"' : "" ?> title="<?= _("Benachrichtigungen") ?>" data-lastvisit="<?= $lastvisit ?>">
+                    <div id="notification_marker"<?= !empty($alert) ? ' class="alert"' : "" ?> title="<?= _("Benachrichtigungen") ?>" data-lastvisit="<?= $lastvisit ?>">
                         <?= count($notifications) ?>
                     </div>
                     <div class="list below" id="notification_list">
diff --git a/templates/index_nobody.php b/templates/index_nobody.php
index f5b91825ce3..8e09f2586c3 100644
--- a/templates/index_nobody.php
+++ b/templates/index_nobody.php
@@ -18,7 +18,7 @@ if ($bg_mobile) {
 ?>
 <!-- Startseite (nicht eingeloggt) -->
 <ul id="tabs" role="navigation"></ul>
-<? if ($logout) : ?>
+<? if (!empty($logout)) : ?>
     <?= MessageBox::success(_("Sie sind nun aus dem System abgemeldet."), array_filter([$GLOBALS['UNI_LOGOUT_ADD']])) ?>
 <? endif; ?>
 
@@ -29,7 +29,7 @@ if ($bg_mobile) {
         <h1><?= htmlReady(Config::get()->UNI_NAME_CLEAN) ?></h1>
         <? foreach (Navigation::getItem('/login') as $key => $nav) : ?>
             <? if ($nav->isVisible()) : ?>
-                <? list($name, $title) = explode(' - ', $nav->getTitle()) ?>
+                <? $name_and_title = explode(' - ', $nav->getTitle()) ?>
                 <div class="login_link">
                     <? if (is_internal_url($url = $nav->getURL())) : ?>
                         <? SkipLinks::addLink($name, $url) ?>
@@ -37,9 +37,9 @@ if ($bg_mobile) {
                     <? else : ?>
                         <a href="<?= htmlReady($url) ?>" target="_blank" rel="noopener noreferrer">
                     <? endif ?>
-                            <?= htmlReady($name) ?>
+                            <?= htmlReady($name_and_title[0]) ?>
                             <p>
-                                <?= htmlReady($title ?: $nav->getDescription()) ?>
+                                <?= htmlReady(!empty($name_and_title[1]) ? $name_and_title[1] : $nav->getDescription()) ?>
                             </p>
                         </a>
                 </div>
diff --git a/templates/layouts/base.php b/templates/layouts/base.php
index f8cd4902146..1a0ce60ba8a 100644
--- a/templates/layouts/base.php
+++ b/templates/layouts/base.php
@@ -1,5 +1,5 @@
 <?php
-NotificationCenter::postNotification('PageWillRender', $body_id ? : PageLayout::getBodyElementId());
+NotificationCenter::postNotification('PageWillRender', PageLayout::getBodyElementId());
 $navigation = PageLayout::getTabNavigation();
 $tab_root_path = PageLayout::getTabNavigationPath();
 if ($navigation) {
@@ -94,7 +94,7 @@ $getInstalledLanguages = function () {
     </script>
 </head>
 
-<body id="<?= $body_id ?: PageLayout::getBodyElementId() ?>" <? if (SkipLinks::isEnabled()) echo 'class="enable-skiplinks"'; ?>>
+<body id="<?= PageLayout::getBodyElementId() ?>" <? if (SkipLinks::isEnabled()) echo 'class="enable-skiplinks"'; ?>>
 <div id="layout_wrapper">
     <? SkipLinks::insertContainer() ?>
     <? SkipLinks::addIndex(_('Hauptinhalt'), 'layout_content', 100) ?>
@@ -134,7 +134,7 @@ $getInstalledLanguages = function () {
         <? endif ?>
 
         <? if (PageLayout::isHeaderEnabled() /*&& isset($navigation)*/) : ?>
-            <?= $this->render_partial('tabs', compact('navigation', 'membership')) ?>
+            <?= $this->render_partial('tabs', compact('navigation')) ?>
         <? endif; ?>
         </nav>
     <? endif; ?>
@@ -167,7 +167,7 @@ $getInstalledLanguages = function () {
                 <? else: ?>
                     <?= htmlReady( PageLayout::getTitle()) ?>
                 <? endif ?>
-                <?= $public_hint ? '(' . htmlReady($public_hint) . ')' : '' ?>
+                <?= !empty($public_hint) ? '(' . htmlReady($public_hint) . ')' : '' ?>
             </div>
         </div>
 
@@ -183,7 +183,7 @@ $getInstalledLanguages = function () {
         </div>
     </div> <? // Closes #layout_page opened in included templates/header.php ?>
 
-    <?= $this->render_partial('footer'); ?>
+    <?= $this->render_partial('footer', ['link_params' => $header_template->link_params]); ?>
     <!-- Ende Page -->
     <? /* <div id="layout_push"></div> */ ?>
 </div>
@@ -195,4 +195,4 @@ $getInstalledLanguages = function () {
     </a>
 </body>
 </html>
-<?php NotificationCenter::postNotification('PageDidRender', $body_id ? : PageLayout::getBodyElementId());
+<?php NotificationCenter::postNotification('PageDidRender', PageLayout::getBodyElementId());
diff --git a/templates/sidebar/list-widget.php b/templates/sidebar/list-widget.php
index 7cee7cdf638..b396455166a 100644
--- a/templates/sidebar/list-widget.php
+++ b/templates/sidebar/list-widget.php
@@ -1,12 +1,14 @@
 <ul class="<?= implode(' ', $css_classes) ?>">
 <? foreach ($elements as $index => $element): ?>
-    <? $icon = $element->icon; ?>
-    <? if ($icon && $element instanceof LinkElement && $element->isDisabled()): ?>
-        <? $icon = $icon->copyWithRole('inactive') ?>
+    <? if ($element instanceof LinkElement): ?>
+        <? $icon = $element->icon ?? null ?>
+        <? if ($icon && $element->isDisabled()): ?>
+            <? $icon = $icon->copyWithRole('inactive') ?>
+        <? endif ?>
     <? endif ?>
     <li id="<?= htmlReady($index) ?>"
-        <?= $icon ? 'style="' . $icon->asCSS() .'"' : '' ?>
-        <?= $element->active ? 'class="active"' : '' ?>>
+        <?= isset($icon) ? 'style="' . $icon->asCSS() .'"' : '' ?>
+        <?= !empty($element->active) ? 'class="active"' : '' ?>>
         <?= $element->render() ?>
     </li>
 <? endforeach; ?>
diff --git a/templates/sidebar/widget-layout.php b/templates/sidebar/widget-layout.php
index de3f82fb74e..7fc3a0c6760 100644
--- a/templates/sidebar/widget-layout.php
+++ b/templates/sidebar/widget-layout.php
@@ -1,9 +1,8 @@
-<div class="<?= $base_class ?>-widget <? if ($layout_css_classes && is_array($layout_css_classes)) echo htmlReady(implode(' ', $layout_css_classes)); ?>"
-    <? if ($id) printf('id="%s"', htmlReady($id)) ?>
-    <? if ($style) printf('style="%s"', $style) ?>>
+<div class="<?= $base_class ?>-widget <?= is_array($layout_css_classes) ? htmlReady(implode(' ', $layout_css_classes)) : '' ?>"
+    <?= !empty($id) ? sprintf('id="%s"', htmlReady($id)) : '' ?>>
 <? if ($title): ?>
     <div class="<?= $base_class ?>-widget-header">
-    <? if ($extra): ?>
+    <? if (isset($extra)): ?>
         <div class="<?= $base_class ?>-widget-extra"><?= $extra ?></div>
     <? endif; ?>
         <?= htmlReady($title) ?>
-- 
GitLab