Add method to get all subscribers of an object
authorjoshuaruesweg <ruesweg@woltlab.com>
Tue, 21 Sep 2021 09:23:51 +0000 (11:23 +0200)
committerjoshuaruesweg <ruesweg@woltlab.com>
Tue, 21 Sep 2021 10:11:37 +0000 (12:11 +0200)
wcfsetup/install/files/lib/data/article/category/ArticleCategory.class.php
wcfsetup/install/files/lib/system/user/object/watch/UserObjectWatchHandler.class.php

index fee8d6160e3dbb1a778e32e35dbcffe7543ac4ae..bfc0dffbf873c3ffeaedec279de8cda900aaf2dc 100644 (file)
@@ -204,15 +204,12 @@ class ArticleCategory extends AbstractDecoratedCategory implements IAccessibleOb
      */
     public function getSubscribedUserIDs(): array
     {
-        $objectTypeID = UserObjectWatchHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.article.category');
-        $sql = "SELECT  userID
-                FROM    wcf" . WCF_N . "_user_object_watch
-                WHERE   objectTypeID = ?
-                    AND objectID = ?";
-        $statement = WCF::getDB()->prepareStatement($sql);
-        $statement->execute([$objectTypeID, $this->categoryID]);
-
-        return $statement->fetchAll(\PDO::FETCH_COLUMN);
+        $subscribers = UserObjectWatchHandler::getInstance()->getSubscribers(
+            'com.woltlab.wcf.article.category',
+            $this->categoryID
+        );
+
+        return \array_keys($subscribers);
     }
 
     /**
index 48c332c0c344312f88d8f999b066a5a396d68ff4..cbf3bcacf816cb3c0cc3bea95613ae597733b3f8 100644 (file)
@@ -120,28 +120,21 @@ class UserObjectWatchHandler extends SingletonFactory
         IUserNotificationObject $notificationObject,
         array $additionalData = []
     ) {
-        // get object type id
         $objectTypeObj = ObjectTypeCache::getInstance()
             ->getObjectTypeByName('com.woltlab.wcf.user.objectWatch', $objectType);
-
-        // get subscriber
-        $userIDs = $recipientIDs = [];
-        $sql = "SELECT  userID, notification
-                FROM    wcf" . WCF_N . "_user_object_watch
-                WHERE   objectTypeID = ?
-                    AND objectID = ?";
-        $statement = WCF::getDB()->prepareStatement($sql);
-        $statement->execute([$objectTypeObj->objectTypeID, $objectID]);
-        while ($row = $statement->fetchArray()) {
-            $userIDs[] = $row['userID'];
-            if ($row['notification'] && $notificationObject->getAuthorID() != $row['userID']) {
-                $recipientIDs[] = $row['userID'];
-            }
-        }
+        $userIDs = $this->getSubscribers($objectType, $objectID);
 
         if (!empty($userIDs)) {
             // reset user storage
-            $objectTypeObj->getProcessor()->resetUserStorage($userIDs);
+            $objectTypeObj->getProcessor()->resetUserStorage(\array_keys($userIDs));
+
+            $recipientIDs = \array_filter(
+                $userIDs,
+                static function ($notification, $userID) use ($notificationObject) {
+                    return $notification && $userID != $notificationObject->getAuthorID();
+                },
+                \ARRAY_FILTER_USE_BOTH
+            );
 
             if (!empty($recipientIDs)) {
                 // create notifications
@@ -149,10 +142,34 @@ class UserObjectWatchHandler extends SingletonFactory
                     $notificationEventName,
                     $notificationObjectType,
                     $notificationObject,
-                    $recipientIDs,
+                    \array_keys($recipientIDs),
                     $additionalData
                 );
             }
         }
     }
+
+    /**
+     * Returns the subscribers for a specific object as an array.
+     * The array key indicates the userID and the array value indicates
+     * the notification status (`1` = should get a notification,
+     * `0` = should not get a notification).
+     *
+     * @since 5.5
+     */
+    public function getSubscribers(string $objectType, int $objectID): array
+    {
+        $objectTypeObj = ObjectTypeCache::getInstance()
+            ->getObjectTypeByName('com.woltlab.wcf.user.objectWatch', $objectType);
+
+        $userIDs = [];
+        $sql = "SELECT  userID, notification
+                FROM    wcf" . WCF_N . "_user_object_watch
+                WHERE   objectTypeID = ?
+                    AND objectID = ?";
+        $statement = WCF::getDB()->prepareStatement($sql);
+        $statement->execute([$objectTypeObj->objectTypeID, $objectID]);
+
+        return $statement->fetchMap('userID', 'notification');
+    }
 }