diff --git a/admin/pages/news.php b/admin/pages/news.php
index d74d6405..61571597 100644
--- a/admin/pages/news.php
+++ b/admin/pages/news.php
@@ -26,7 +26,7 @@ if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
 
 header('X-XSS-Protection:0');
 
-// some constants, used mainly by database (cannot by modified without schema changes)
+// some constants, used mainly by database (cannot be modified without schema changes)
 const NEWS_TITLE_LIMIT = 100;
 const NEWS_BODY_LIMIT = 65535; // maximum news body length
 const ARTICLE_TEXT_LIMIT = 300;
@@ -136,9 +136,18 @@ if($action == 'edit' || $action == 'new') {
 
 $query = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news'));
 $newses = array();
+
+$cachePlayers = [];
 foreach ($query as $_news) {
-	$_player = new OTS_Player();
-	$_player->load($_news['player_id']);
+	$playerId = $_news['player_id'];
+	if (isset($cachePlayers[$playerId])) {
+		$_player = $cachePlayers[$playerId];
+	}
+	else {
+		$_player = new OTS_Player();
+		$_player->load($playerId);
+		$cachePlayers[$playerId] = $_player;
+	}
 
 	$newses[$_news['type']][] = array(
 		'id' => $_news['id'],
@@ -147,7 +156,7 @@ foreach ($query as $_news) {
 		'title' => $_news['title'],
 		'date' => $_news['date'],
 		'player_name' => $_player->isLoaded() ? $_player->getName() : '',
-		'player_link' => $_player->isLoaded() ? getPlayerLink($_player->getName(), false) : '',
+		'player_link' => $_player->isLoaded() ? getPlayerLink($_player, false) : '',
 	);
 }
 
diff --git a/composer.json b/composer.json
index 47d68dbe..de66b921 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
 {
     "require": {
-        "php": "^8.0",
+        "php": "^8.1",
         "ext-pdo": "*",
         "ext-pdo_mysql": "*",
         "ext-json": "*",
diff --git a/system/functions.php b/system/functions.php
index f177d997..09f122fe 100644
--- a/system/functions.php
+++ b/system/functions.php
@@ -89,13 +89,18 @@ function getForumBoardLink($board_id, $page = NULL): string {
 
 function getPlayerLink($name, $generate = true, bool $colored = false): string
 {
-	$player = new OTS_Player();
-
-	if(is_numeric($name)) {
-		$player->load((int)$name);
+	if (is_object($name) and $name instanceof OTS_Player) {
+		$player = $name;
 	}
 	else {
-		$player->find($name);
+		$player = new OTS_Player();
+
+		if(is_numeric($name)) {
+			$player->load((int)$name);
+		}
+		else {
+			$player->find($name);
+		}
 	}
 
 	if (!$player->isLoaded()) {
diff --git a/system/init.php b/system/init.php
index 560a6100..68122dba 100644
--- a/system/init.php
+++ b/system/init.php
@@ -39,7 +39,7 @@ if($config['server_path'][strlen($config['server_path']) - 1] !== '/')
 	$config['server_path'] .= '/';
 
 // enable gzip compression if supported by the browser
-if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler'))
+if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('ob_gzhandler'))
 	ob_start('ob_gzhandler');
 
 // cache
diff --git a/system/libs/pot/OTS_DB_MySQL.php b/system/libs/pot/OTS_DB_MySQL.php
index 5ca7d28b..89e8dd0d 100644
--- a/system/libs/pot/OTS_DB_MySQL.php
+++ b/system/libs/pot/OTS_DB_MySQL.php
@@ -53,49 +53,49 @@ class OTS_DB_MySQL extends OTS_Base_DB
  * @param array $params Connection parameters.
  * @throws PDOException On PDO operation error.
  */
-    public function __construct($params)
-    {
-        $user = null;
-        $password = null;
-        $dns = array();
+	public function __construct($params)
+	{
+		$user = null;
+		$password = null;
+		$dns = array();
 
-        // host:port support
-        if( strpos(':', $params['host']) !== false)
-        {
-            $host = explode(':', $params['host'], 2);
+		// host:port support
+		if( strpos(':', $params['host']) !== false)
+		{
+			$host = explode(':', $params['host'], 2);
 
-            $params['host'] = $host[0];
-            $params['port'] = $host[1];
-        }
+			$params['host'] = $host[0];
+			$params['port'] = $host[1];
+		}
 
-        if( isset($params['database']) )
-        {
-            $dns[] = 'dbname=' . $params['database'];
-        }
+		if( isset($params['database']) )
+		{
+			$dns[] = 'dbname=' . $params['database'];
+		}
 
-        if( isset($params['user']) )
-        {
-            $user = $params['user'];
-        }
+		if( isset($params['user']) )
+		{
+			$user = $params['user'];
+		}
 
-        if( isset($params['password']) )
-        {
-            $password = $params['password'];
-        }
+		if( isset($params['password']) )
+		{
+			$password = $params['password'];
+		}
 
-        if( isset($params['prefix']) )
-        {
-            $this->prefix = $params['prefix'];
-        }
+		if( isset($params['prefix']) )
+		{
+			$this->prefix = $params['prefix'];
+		}
 
-        if( isset($params['log']) && $params['log'] )
-        {
-            $this->logged = true;
-        }
+		if( isset($params['log']) && $params['log'] )
+		{
+			$this->logged = true;
+		}
 
-        if( !isset($params['persistent']) ) {
-            $params['persistent'] = false;
-        }
+		if( !isset($params['persistent']) ) {
+			$params['persistent'] = false;
+		}
 
 		global $config;
 		$cache = Cache::getInstance();
@@ -144,10 +144,10 @@ class OTS_DB_MySQL extends OTS_Base_DB
 		}
 
 		parent::__construct('mysql:' . implode(';', $dns), $user, $password, $driverAttributes);
-    }
+	}
 
 	public function __destruct()
-    {
+	{
 		global $config;
 
 		$cache = Cache::getInstance();
@@ -165,7 +165,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
 		}
 
 		if($this->logged) {
-			log_append('database.log', $_SERVER['REQUEST_URI'] . PHP_EOL . $this->getLog());
+			$currentScript = $_SERVER['REQUEST_URI'] ?? $_SERVER['SCRIPT_FILENAME'];
+			log_append('database.log', $currentScript . PHP_EOL . $this->getLog());
 		}
 	}
 
@@ -175,10 +176,10 @@ class OTS_DB_MySQL extends OTS_Base_DB
  * @param string $name Field name.
  * @return string Quoted name.
  */
-    public function fieldName($name)
-    {
-        return '`' . $name . '`';
-    }
+	public function fieldName($name)
+	{
+		return '`' . $name . '`';
+	}
 
 /**
  * LIMIT/OFFSET clause for queries.
@@ -187,26 +188,26 @@ class OTS_DB_MySQL extends OTS_Base_DB
  * @param int|bool $offset Number of rows to be skipped before applying query effects (false if no offset).
  * @return string LIMIT/OFFSET SQL clause for query.
  */
-    public function limit($limit = false, $offset = false)
-    {
-        // by default this is empty part
-        $sql = '';
+	public function limit($limit = false, $offset = false)
+	{
+		// by default this is empty part
+		$sql = '';
 
-        if($limit !== false)
-        {
-            $sql = ' LIMIT ';
+		if($limit !== false)
+		{
+			$sql = ' LIMIT ';
 
-            // OFFSET has no effect if there is no LIMIT
-            if($offset !== false)
-            {
-                $sql .= $offset . ', ';
-            }
+			// OFFSET has no effect if there is no LIMIT
+			if($offset !== false)
+			{
+				$sql .= $offset . ', ';
+			}
 
-            $sql .= $limit;
-        }
+			$sql .= $limit;
+		}
 
-        return $sql;
-    }
+		return $sql;
+	}
 
 	public function hasTable($name) {
 		if(isset($this->has_table_cache[$name])) {
diff --git a/system/src/Cache.php b/system/src/Cache.php
new file mode 100644
index 00000000..42ca597f
--- /dev/null
+++ b/system/src/Cache.php
@@ -0,0 +1,5 @@
+<?php
+
+namespace MyAAC;
+
+class Cache extends Cache\Cache {}
diff --git a/system/src/Plugins.php b/system/src/Plugins.php
index fbaa5e40..00515139 100644
--- a/system/src/Plugins.php
+++ b/system/src/Plugins.php
@@ -766,22 +766,21 @@ class Plugins {
 	 * Helper function for plugins
 	 *
 	 * @param string $templateName
-	 * @param array $categories
+	 * @param array $menus
 	 */
-	public static function installMenus($templateName, $categories, $clearOld = true)
+	public static function installMenus($templateName, $menus, $clearOld = false)
 	{
-		global $db;
-		if (!$db->hasTable(TABLE_PREFIX . 'menu')) {
-			return;
-		}
-
 		if ($clearOld) {
 			Menu::where('template', $templateName)->delete();
 		}
 
-		foreach ($categories as $category => $menus) {
+		if (Menu::where('template', $templateName)->count()) {
+			return;
+		}
+
+		foreach ($menus as $category => $_menus) {
 			$i = 0;
-			foreach ($menus as $name => $link) {
+			foreach ($_menus as $name => $link) {
 				$color = '';
 				$blank = 0;
 
diff --git a/system/twig.php b/system/twig.php
index 9176c371..1268f292 100644
--- a/system/twig.php
+++ b/system/twig.php
@@ -16,6 +16,8 @@ use Twig\Loader\FilesystemLoader as Twig_FilesystemLoader;
 use Twig\TwigFilter;
 use Twig\TwigFunction;
 
+global $twig, $twig_loader;
+
 $dev_mode = (config('env') === 'dev');
 $twig_loader = new Twig_FilesystemLoader(SYSTEM . 'templates');
 $twig = new Twig_Environment($twig_loader, array(
diff --git a/templates/tibiacom/account.management.html.twig b/templates/tibiacom/account.management.html.twig
index 6ce10274..5125f3ed 100644
--- a/templates/tibiacom/account.management.html.twig
+++ b/templates/tibiacom/account.management.html.twig
@@ -291,7 +291,7 @@
 		</a>
 	</div>
 </div>
-{% set title = 'Account logs' %}
+{% set title = 'Account Logs' %}
 {% set tableClass = 'Table3' %}
 {% set content %}
 <table style="width:100%;">