Do not update `confirmTime` for read notifications (#4129)
authorTim Düsterhus <duesterhus@woltlab.com>
Mon, 19 Apr 2021 11:42:34 +0000 (13:42 +0200)
committerGitHub <noreply@github.com>
Mon, 19 Apr 2021 11:42:34 +0000 (13:42 +0200)
Co-authored-by: Matthias Schmidt <gravatronics@live.com>
wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php

index f6fca466a50f2f62d282ad278c7c7a87a0185fbc..fbdecf2ffa62d0ee51df1c7cb25e704842cb86a2 100644 (file)
@@ -909,6 +909,7 @@ class UserNotificationHandler extends SingletonFactory
 
         // mark as confirmed
         $conditions = new PreparedStatementConditionBuilder();
+        $conditions->add("confirmTime = ?", [0]);
         $conditions->add("eventID = ?", [$event->eventID]);
         if (!empty($recipientIDs)) {
             $conditions->add("userID IN (?)", [$recipientIDs]);
@@ -924,6 +925,7 @@ class UserNotificationHandler extends SingletonFactory
         $parameters = $conditions->getParameters();
         \array_unshift($parameters, TIME_NOW);
         $statement->execute($parameters);
+        $confirmedCount = $statement->getAffectedRows();
 
         $parameters = [
             'event' => $event,
@@ -934,21 +936,23 @@ class UserNotificationHandler extends SingletonFactory
         ];
         EventHandler::getInstance()->fireAction($this, 'markAsConfirmed', $parameters);
 
-        // delete notification_to_user assignments (mimic legacy notification system)
-        $sql = "DELETE FROM wcf" . WCF_N . "_user_notification_to_user
-                WHERE       notificationID NOT IN (
-                                SELECT  notificationID
-                                FROM    wcf" . WCF_N . "_user_notification
-                                WHERE   confirmTime = ?
-                            )";
-        $statement = WCF::getDB()->prepareStatement($sql);
-        $statement->execute([0]);
+        // Check whether anything was changed. If not, we don't need to do anything else.
+        if ($confirmedCount) {
+            // delete notification_to_user assignments (mimic legacy notification system)
+            $sql = "DELETE FROM wcf" . WCF_N . "_user_notification_to_user
+                    WHERE       notificationID NOT IN (
+                                    SELECT  notificationID
+                                    FROM    wcf" . WCF_N . "_user_notification
+                                    WHERE   confirmTime = ?
+                                )";
+            $statement = WCF::getDB()->prepareStatement($sql);
+            $statement->execute([0]);
 
-        // reset storage
-        if (!empty($recipientIDs)) {
-            UserStorageHandler::getInstance()->reset($recipientIDs, 'userNotificationCount');
-        } else {
-            UserStorageHandler::getInstance()->resetAll('userNotificationCount');
+            if (!empty($recipientIDs)) {
+                UserStorageHandler::getInstance()->reset($recipientIDs, 'userNotificationCount');
+            } else {
+                UserStorageHandler::getInstance()->resetAll('userNotificationCount');
+            }
         }
     }
 
@@ -976,6 +980,7 @@ class UserNotificationHandler extends SingletonFactory
 
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("notificationID IN (?)", [$notificationIDs]);
+        $conditions->add("confirmTime = ?", [0]);
 
         // mark notifications as confirmed
         $sql = "UPDATE  wcf" . WCF_N . "_user_notification
@@ -985,18 +990,24 @@ class UserNotificationHandler extends SingletonFactory
         $parameters = $conditions->getParameters();
         \array_unshift($parameters, TIME_NOW);
         $statement->execute($parameters);
+        $confirmedCount = $statement->getAffectedRows();
 
         $parameters = ['notificationIDs' => $notificationIDs];
         EventHandler::getInstance()->fireAction($this, 'markAsConfirmedByIDs', $parameters);
 
-        // delete notification_to_user assignments (mimic legacy notification system)
-        $sql = "DELETE FROM wcf" . WCF_N . "_user_notification_to_user
-                " . $conditions;
-        $statement = WCF::getDB()->prepareStatement($sql);
-        $statement->execute($conditions->getParameters());
+        // Check whether anything was changed. If not, we don't need to do anything else.
+        if ($confirmedCount) {
+            $conditions = new PreparedStatementConditionBuilder();
+            $conditions->add("notificationID IN (?)", [$notificationIDs]);
 
-        // reset user storage
-        UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'userNotificationCount');
+            // delete notification_to_user assignments (mimic legacy notification system)
+            $sql = "DELETE FROM wcf" . WCF_N . "_user_notification_to_user
+                    " . $conditions;
+            $statement = WCF::getDB()->prepareStatement($sql);
+            $statement->execute($conditions->getParameters());
+
+            UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'userNotificationCount');
+        }
     }
 
     /**