]> BookStack Code Mirror - bookstack/blob - app/Activity/Tools/UserWatchOptions.php
Notifications: Linked watch functionality to UI
[bookstack] / app / Activity / Tools / UserWatchOptions.php
1 <?php
2
3 namespace BookStack\Activity\Tools;
4
5 use BookStack\Activity\Models\Watch;
6 use BookStack\Entities\Models\Entity;
7 use BookStack\Users\Models\User;
8 use Illuminate\Database\Eloquent\Builder;
9
10 class UserWatchOptions
11 {
12     protected static array $levelByName = [
13         'default' => -1,
14         'ignore' => 0,
15         'new' => 1,
16         'updates' => 2,
17         'comments' => 3,
18     ];
19
20     public function __construct(
21         protected User $user,
22     ) {
23     }
24
25     public function canWatch(): bool
26     {
27         return $this->user->can('receive-notifications') && !$this->user->isDefault();
28     }
29
30     public function getEntityWatchLevel(Entity $entity): string
31     {
32         $levelValue = $this->entityQuery($entity)->first(['level'])->level ?? -1;
33         return $this->levelValueToName($levelValue);
34     }
35
36     public function isWatching(Entity $entity): bool
37     {
38         return $this->entityQuery($entity)->exists();
39     }
40
41     public function updateEntityWatchLevel(Entity $entity, string $level): void
42     {
43         $levelValue = $this->levelNameToValue($level);
44         if ($levelValue < 0) {
45             $this->removeForEntity($entity);
46             return;
47         }
48
49         $this->updateForEntity($entity, $levelValue);
50     }
51
52     protected function updateForEntity(Entity $entity, int $levelValue): void
53     {
54         Watch::query()->updateOrCreate([
55             'watchable_id' => $entity->id,
56             'watchable_type' => $entity->getMorphClass(),
57             'user_id' => $this->user->id,
58         ], [
59             'level' => $levelValue,
60         ]);
61     }
62
63     protected function removeForEntity(Entity $entity): void
64     {
65         $this->entityQuery($entity)->delete();
66     }
67
68     protected function entityQuery(Entity $entity): Builder
69     {
70         return Watch::query()->where('watchable_id', '=', $entity->id)
71             ->where('watchable_type', '=', $entity->getMorphClass())
72             ->where('user_id', '=', $this->user->id);
73     }
74
75     /**
76      * @return string[]
77      */
78     public static function getAvailableLevelNames(): array
79     {
80         return array_keys(static::$levelByName);
81     }
82
83     protected static function levelNameToValue(string $level): int
84     {
85         return static::$levelByName[$level] ?? -1;
86     }
87
88     protected static function levelValueToName(int $level): string
89     {
90         foreach (static::$levelByName as $name => $value) {
91             if ($level === $value) {
92                 return $name;
93             }
94         }
95
96         return 'default';
97     }
98 }