mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-11-03 02:13:16 +03:00 
			
		
		
		
	- Moves guest user caching from User class to app container for simplicity. - Updates test to use simpler $this->users->guest() method for consistency. - Streamlined helpers to avoid function overlap for simplicity. - Extracted user profile dropdown while doing changes.
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace BookStack\Activity\Tools;
 | 
						|
 | 
						|
use BookStack\Activity\Models\Watch;
 | 
						|
use BookStack\Activity\WatchLevels;
 | 
						|
use BookStack\Entities\Models\BookChild;
 | 
						|
use BookStack\Entities\Models\Entity;
 | 
						|
use BookStack\Entities\Models\Page;
 | 
						|
use BookStack\Users\Models\User;
 | 
						|
use Illuminate\Database\Eloquent\Builder;
 | 
						|
 | 
						|
class UserEntityWatchOptions
 | 
						|
{
 | 
						|
    protected ?array $watchMap = null;
 | 
						|
 | 
						|
    public function __construct(
 | 
						|
        protected User $user,
 | 
						|
        protected Entity $entity,
 | 
						|
    ) {
 | 
						|
    }
 | 
						|
 | 
						|
    public function canWatch(): bool
 | 
						|
    {
 | 
						|
        return $this->user->can('receive-notifications') && !$this->user->isGuest();
 | 
						|
    }
 | 
						|
 | 
						|
    public function getWatchLevel(): string
 | 
						|
    {
 | 
						|
        return WatchLevels::levelValueToName($this->getWatchLevelValue());
 | 
						|
    }
 | 
						|
 | 
						|
    public function isWatching(): bool
 | 
						|
    {
 | 
						|
        return $this->getWatchLevelValue() !== WatchLevels::DEFAULT;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getWatchedParent(): ?WatchedParentDetails
 | 
						|
    {
 | 
						|
        $watchMap = $this->getWatchMap();
 | 
						|
        unset($watchMap[$this->entity->getMorphClass()]);
 | 
						|
 | 
						|
        if (isset($watchMap['chapter'])) {
 | 
						|
            return new WatchedParentDetails('chapter', $watchMap['chapter']);
 | 
						|
        }
 | 
						|
 | 
						|
        if (isset($watchMap['book'])) {
 | 
						|
            return new WatchedParentDetails('book', $watchMap['book']);
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function updateLevelByName(string $level): void
 | 
						|
    {
 | 
						|
        $levelValue = WatchLevels::levelNameToValue($level);
 | 
						|
        $this->updateLevelByValue($levelValue);
 | 
						|
    }
 | 
						|
 | 
						|
    public function updateLevelByValue(int $level): void
 | 
						|
    {
 | 
						|
        if ($level < 0) {
 | 
						|
            $this->remove();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $this->updateLevel($level);
 | 
						|
    }
 | 
						|
 | 
						|
    public function getWatchMap(): array
 | 
						|
    {
 | 
						|
        if (!is_null($this->watchMap)) {
 | 
						|
            return $this->watchMap;
 | 
						|
        }
 | 
						|
 | 
						|
        $entities = [$this->entity];
 | 
						|
        if ($this->entity instanceof BookChild) {
 | 
						|
            $entities[] = $this->entity->book;
 | 
						|
        }
 | 
						|
        if ($this->entity instanceof Page && $this->entity->chapter) {
 | 
						|
            $entities[] = $this->entity->chapter;
 | 
						|
        }
 | 
						|
 | 
						|
        $query = Watch::query()
 | 
						|
            ->where('user_id', '=', $this->user->id)
 | 
						|
            ->where(function (Builder $subQuery) use ($entities) {
 | 
						|
                foreach ($entities as $entity) {
 | 
						|
                    $subQuery->orWhere(function (Builder $whereQuery) use ($entity) {
 | 
						|
                        $whereQuery->where('watchable_type', '=', $entity->getMorphClass())
 | 
						|
                        ->where('watchable_id', '=', $entity->id);
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
        $this->watchMap = $query->get(['watchable_type', 'level'])
 | 
						|
            ->pluck('level', 'watchable_type')
 | 
						|
            ->toArray();
 | 
						|
 | 
						|
        return $this->watchMap;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function getWatchLevelValue()
 | 
						|
    {
 | 
						|
        return $this->getWatchMap()[$this->entity->getMorphClass()] ?? WatchLevels::DEFAULT;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function updateLevel(int $levelValue): void
 | 
						|
    {
 | 
						|
        Watch::query()->updateOrCreate([
 | 
						|
            'watchable_id' => $this->entity->id,
 | 
						|
            'watchable_type' => $this->entity->getMorphClass(),
 | 
						|
            'user_id' => $this->user->id,
 | 
						|
        ], [
 | 
						|
            'level' => $levelValue,
 | 
						|
        ]);
 | 
						|
        $this->watchMap = null;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function remove(): void
 | 
						|
    {
 | 
						|
        $this->entityQuery()->delete();
 | 
						|
        $this->watchMap = null;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function entityQuery(): Builder
 | 
						|
    {
 | 
						|
        return Watch::query()->where('watchable_id', '=', $this->entity->id)
 | 
						|
            ->where('watchable_type', '=', $this->entity->getMorphClass())
 | 
						|
            ->where('user_id', '=', $this->user->id);
 | 
						|
    }
 | 
						|
}
 |