1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-30 04:23:11 +03:00

Notifications: Started core user notification logic

Put together an initial notification.
Started logic to query and identify watchers.
This commit is contained in:
Dan Brown
2023-08-04 12:27:29 +01:00
parent 9d149e4d36
commit 9779c1a357
13 changed files with 258 additions and 42 deletions

View File

@ -40,7 +40,7 @@ class ActivityLogger
$this->setNotification($type);
$this->dispatchWebhooks($type, $detail);
$this->notifications->handle($type, $detail);
$this->notifications->handle($type, $detail, user());
Theme::dispatch(ThemeEvents::ACTIVITY_LOGGED, $type, $detail);
}

View File

@ -0,0 +1,55 @@
<?php
namespace BookStack\Activity\Tools;
use BookStack\Activity\Models\Watch;
use BookStack\Entities\Models\BookChild;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use Illuminate\Database\Eloquent\Builder;
class EntityWatchers
{
protected array $watchers = [];
protected array $ignorers = [];
public function __construct(
protected Entity $entity,
protected int $watchLevel,
) {
$this->build();
}
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.
}
protected function getRelevantWatches(): array
{
/** @var Entity[] $entitiesInvolved */
$entitiesInvolved = array_filter([
$this->entity,
$this->entity instanceof BookChild ? $this->entity->book : null,
$this->entity instanceof Page ? $this->entity->chapter : null,
]);
$query = Watch::query()->where(function (Builder $query) use ($entitiesInvolved) {
foreach ($entitiesInvolved as $entity) {
$query->orWhere(function (Builder $query) use ($entity) {
$query->where('watchable_type', '=', $entity->getMorphClass())
->where('watchable_id', '=', $entity->id);
});
}
});
return $query->get([
'level', 'watchable_id', 'watchable_type', 'user_id'
])->all();
}
}

View File

@ -3,20 +3,13 @@
namespace BookStack\Activity\Tools;
use BookStack\Activity\Models\Watch;
use BookStack\Activity\WatchLevels;
use BookStack\Entities\Models\Entity;
use BookStack\Users\Models\User;
use Illuminate\Database\Eloquent\Builder;
class UserWatchOptions
{
protected static array $levelByName = [
'default' => -1,
'ignore' => 0,
'new' => 1,
'updates' => 2,
'comments' => 3,
];
public function __construct(
protected User $user,
) {
@ -30,7 +23,7 @@ class UserWatchOptions
public function getEntityWatchLevel(Entity $entity): string
{
$levelValue = $this->entityQuery($entity)->first(['level'])->level ?? -1;
return $this->levelValueToName($levelValue);
return WatchLevels::levelValueToName($levelValue);
}
public function isWatching(Entity $entity): bool
@ -40,7 +33,7 @@ class UserWatchOptions
public function updateEntityWatchLevel(Entity $entity, string $level): void
{
$levelValue = $this->levelNameToValue($level);
$levelValue = WatchLevels::levelNameToValue($level);
if ($levelValue < 0) {
$this->removeForEntity($entity);
return;
@ -71,28 +64,4 @@ class UserWatchOptions
->where('watchable_type', '=', $entity->getMorphClass())
->where('user_id', '=', $this->user->id);
}
/**
* @return string[]
*/
public static function getAvailableLevelNames(): array
{
return array_keys(static::$levelByName);
}
protected static function levelNameToValue(string $level): int
{
return static::$levelByName[$level] ?? -1;
}
protected static function levelValueToName(int $level): string
{
foreach (static::$levelByName as $name => $value) {
if ($level === $value) {
return $name;
}
}
return 'default';
}
}