]> BookStack Code Mirror - bookstack/blobdiff - app/Activity/Tools/EntityWatchers.php
Customization: Added parent tag classes
[bookstack] / app / Activity / Tools / EntityWatchers.php
index 20375ef454d9bb108e114d9e2f016c2a5f348a84..1ab53cb1ce0ba1ac13852ebb705b3febe049bd78 100644 (file)
@@ -10,7 +10,14 @@ use Illuminate\Database\Eloquent\Builder;
 
 class EntityWatchers
 {
+    /**
+     * @var int[]
+     */
     protected array $watchers = [];
+
+    /**
+     * @var int[]
+     */
     protected array $ignorers = [];
 
     public function __construct(
@@ -20,16 +27,40 @@ class EntityWatchers
         $this->build();
     }
 
+    public function getWatcherUserIds(): array
+    {
+        return $this->watchers;
+    }
+
+    public function isUserIgnoring(int $userId): bool
+    {
+        return in_array($userId, $this->ignorers);
+    }
+
     protected function build(): void
     {
         $watches = $this->getRelevantWatches();
 
-        // TODO - De-dupe down watches per-user across entity types
-        // so we end up with [user_id => status] values
-        // then filter to current watch level, considering ignores,
-        // then populate the class watchers/ignores with ids.
+        // Sort before de-duping, so that the order looped below follows book -> chapter -> page ordering
+        usort($watches, function (Watch $watchA, Watch $watchB) {
+            $entityTypeDiff = $watchA->watchable_type <=> $watchB->watchable_type;
+            return $entityTypeDiff === 0 ? ($watchA->user_id <=> $watchB->user_id) : $entityTypeDiff;
+        });
+
+        // De-dupe by user id to get their most relevant level
+        $levelByUserId = [];
+        foreach ($watches as $watch) {
+            $levelByUserId[$watch->user_id] = $watch->level;
+        }
+
+        // Populate the class arrays
+        $this->watchers = array_keys(array_filter($levelByUserId, fn(int $level) => $level >= $this->watchLevel));
+        $this->ignorers = array_keys(array_filter($levelByUserId, fn(int $level) => $level === 0));
     }
 
+    /**
+     * @return Watch[]
+     */
     protected function getRelevantWatches(): array
     {
         /** @var Entity[] $entitiesInvolved */
@@ -49,7 +80,7 @@ class EntityWatchers
         });
 
         return $query->get([
-           'level', 'watchable_id', 'watchable_type', 'user_id'
+            'level', 'watchable_id', 'watchable_type', 'user_id'
         ])->all();
     }
 }