diff --git a/composer.json b/composer.json
index f15301506133f8cf866f7b9bee5c25e89565822f..b8047731994b6fe834452607b338445cb8b780aa 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
         "url": "https://www.pcsg.de"
     },
     "require": {
-        "php": "^8.0",
+        "php": "^8.1",
         "quiqqer/core": "^2",
         "quiqqer/erp": "^3.2",
         "quiqqer/areas": "^2",
diff --git a/src/QUI/ERP/Products/Product/Model.php b/src/QUI/ERP/Products/Product/Model.php
index 3febbad5f6d3db04e94c75bbe0f4aa469866e76a..856aafc50126f58e8ad586ab394b36fd1946525e 100644
--- a/src/QUI/ERP/Products/Product/Model.php
+++ b/src/QUI/ERP/Products/Product/Model.php
@@ -351,9 +351,21 @@ public function getViewFrontend(): ViewFrontend
         try {
             return new ViewFrontend($this);
         } catch (\Exception $Exception) {
-            QUI\System\Log::addError($Exception->getMessage(), [
-                'extra-message' => 'product frontend view error'
-            ]);
+            if ($Exception->getCode() === 404) {
+                // log products not found
+                // these are often products that are called up but are deactivated and still exist
+                // e.g. when search engines still direct users to it
+                QUI\System\Log::addError(
+                    $Exception->getMessage(),
+                    ['extra-message' => 'product frontend view error'],
+                    'products_not_found'
+                );
+            } else {
+                QUI\System\Log::addError(
+                    $Exception->getMessage(),
+                    ['extra-message' => 'product frontend view error']
+                );
+            }
 
             throw $Exception;
         }
diff --git a/types/category.php b/types/category.php
index b7ba0a1dcdaf4cd2b87cbd7bd07702ba88f4ba09..02b57c21df0e78b1479e0707b20fdf2985e8a123 100644
--- a/types/category.php
+++ b/types/category.php
@@ -29,7 +29,7 @@
 
 // fallback url for a product, with NO category
 // this should never happen and is a configuration error
-if (strpos(QUI::getRequest()->getPathInfo(), '_p/') !== false) {
+if (str_contains(QUI::getRequest()->getPathInfo(), '_p/')) {
     $_REQUEST['_url'] = QUI::getRequest()->getPathInfo();
 
     if (strlen(URL_DIR) == 1) {
@@ -133,7 +133,7 @@
         }
 
         // if product url is with lang flag /en/
-        if (strpos($productUrl, '/', 1) === 3 && strpos($productUrl, '/_p/') === false) {
+        if (strpos($productUrl, '/', 1) === 3 && !str_contains($productUrl, '/_p/')) {
             $productUrl = mb_substr($productUrl, 3);
         }
 
@@ -304,7 +304,7 @@
     $fields = Products\Utils\Sortables::getSortableFieldsForSite($Site);
 
     foreach ($fields as $fieldId) {
-        if (strpos($fieldId, 'S') === 0) {
+        if (str_starts_with($fieldId, 'S')) {
             $title = QUI::getLocale()->get('quiqqer/products', 'sortable.' . mb_substr($fieldId, 1));
 
             $ProductList->addSort(
@@ -320,7 +320,7 @@
             continue;
         }
 
-        if (strpos($fieldId, 'F') === 0) {
+        if (str_starts_with($fieldId, 'F')) {
             try {
                 $fieldId = str_replace('F', '', $fieldId);
 
@@ -361,7 +361,7 @@
     }
 
     if ($hasFilter && !$ProductList->count()) {
-        // keine produkte -> weiterleitung zu main
+        // keine produkte → weiterleitung zu main
         $Redirect = new RedirectResponse($Site->getUrlRewritten());
         $Redirect->setStatusCode(Response::HTTP_SEE_OTHER);
 
diff --git a/types/productList.php b/types/productList.php
index 558de754d540fa80fe8277dabd436608a5c197aa..b6699687030b9423e5aaa4217283c39924d73c0c 100644
--- a/types/productList.php
+++ b/types/productList.php
@@ -12,7 +12,7 @@
 use QUI\ERP\Products\Handler\Products;
 
 $productIds = $Site->getAttribute('quiqqer.products.settings.productIds');
-$productIds = \explode(',', $productIds);
+$productIds = explode(',', $productIds);
 
 $products = [];