3 namespace BookStack\Activity\Tools;
5 use BookStack\Activity\Models\Watch;
6 use BookStack\Activity\WatchLevels;
7 use BookStack\Entities\Models\BookChild;
8 use BookStack\Entities\Models\Entity;
9 use BookStack\Entities\Models\Page;
10 use BookStack\Users\Models\User;
11 use Illuminate\Database\Eloquent\Builder;
13 class UserEntityWatchOptions
15 protected ?array $watchMap = null;
17 public function __construct(
19 protected Entity $entity,
23 public function canWatch(): bool
25 return $this->user->can('receive-notifications') && !$this->user->isGuest();
28 public function getWatchLevel(): string
30 return WatchLevels::levelValueToName($this->getWatchLevelValue());
33 public function isWatching(): bool
35 return $this->getWatchLevelValue() !== WatchLevels::DEFAULT;
38 public function getWatchedParent(): ?WatchedParentDetails
40 $watchMap = $this->getWatchMap();
41 unset($watchMap[$this->entity->getMorphClass()]);
43 if (isset($watchMap['chapter'])) {
44 return new WatchedParentDetails('chapter', $watchMap['chapter']);
47 if (isset($watchMap['book'])) {
48 return new WatchedParentDetails('book', $watchMap['book']);
54 public function updateLevelByName(string $level): void
56 $levelValue = WatchLevels::levelNameToValue($level);
57 $this->updateLevelByValue($levelValue);
60 public function updateLevelByValue(int $level): void
67 $this->updateLevel($level);
70 public function getWatchMap(): array
72 if (!is_null($this->watchMap)) {
73 return $this->watchMap;
76 $entities = [$this->entity];
77 if ($this->entity instanceof BookChild) {
78 $entities[] = $this->entity->book;
80 if ($this->entity instanceof Page && $this->entity->chapter) {
81 $entities[] = $this->entity->chapter;
84 $query = Watch::query()
85 ->where('user_id', '=', $this->user->id)
86 ->where(function (Builder $subQuery) use ($entities) {
87 foreach ($entities as $entity) {
88 $subQuery->orWhere(function (Builder $whereQuery) use ($entity) {
89 $whereQuery->where('watchable_type', '=', $entity->getMorphClass())
90 ->where('watchable_id', '=', $entity->id);
95 $this->watchMap = $query->get(['watchable_type', 'level'])
96 ->pluck('level', 'watchable_type')
99 return $this->watchMap;
102 protected function getWatchLevelValue()
104 return $this->getWatchMap()[$this->entity->getMorphClass()] ?? WatchLevels::DEFAULT;
107 protected function updateLevel(int $levelValue): void
109 Watch::query()->updateOrCreate([
110 'watchable_id' => $this->entity->id,
111 'watchable_type' => $this->entity->getMorphClass(),
112 'user_id' => $this->user->id,
114 'level' => $levelValue,
116 $this->watchMap = null;
119 protected function remove(): void
121 $this->entityQuery()->delete();
122 $this->watchMap = null;
125 protected function entityQuery(): Builder
127 return Watch::query()->where('watchable_id', '=', $this->entity->id)
128 ->where('watchable_type', '=', $this->entity->getMorphClass())
129 ->where('user_id', '=', $this->user->id);