]> BookStack Code Mirror - bookstack/blob - app/Actions/ViewService.php
Show bookshelves that a book belongs to on a book view
[bookstack] / app / Actions / ViewService.php
1 <?php namespace BookStack\Actions;
2
3 use BookStack\Auth\Permissions\PermissionService;
4 use BookStack\Entities\Entity;
5 use BookStack\Entities\EntityProvider;
6 use DB;
7 use Illuminate\Support\Collection;
8
9 class ViewService
10 {
11     protected $view;
12     protected $permissionService;
13     protected $entityProvider;
14
15     /**
16      * ViewService constructor.
17      * @param View $view
18      * @param PermissionService $permissionService
19      * @param EntityProvider $entityProvider
20      */
21     public function __construct(View $view, PermissionService $permissionService, EntityProvider $entityProvider)
22     {
23         $this->view = $view;
24         $this->permissionService = $permissionService;
25         $this->entityProvider = $entityProvider;
26     }
27
28     /**
29      * Add a view to the given entity.
30      * @param \BookStack\Entities\Entity $entity
31      * @return int
32      */
33     public function add(Entity $entity)
34     {
35         $user = user();
36         if ($user === null || $user->isDefault()) {
37             return 0;
38         }
39         $view = $entity->views()->where('user_id', '=', $user->id)->first();
40         // Add view if model exists
41         if ($view) {
42             $view->increment('views');
43             return $view->views;
44         }
45
46         // Otherwise create new view count
47         $entity->views()->save($this->view->create([
48             'user_id' => $user->id,
49             'views' => 1
50         ]));
51
52         return 1;
53     }
54
55     /**
56      * Get the entities with the most views.
57      * @param int $count
58      * @param int $page
59      * @param string|array $filterModels
60      * @param string $action - used for permission checking
61      * @return Collection
62      */
63     public function getPopular(int $count = 10, int $page = 0, $filterModels = null, string $action = 'view')
64     {
65         $skipCount = $count * $page;
66         $query = $this->permissionService
67             ->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
68             ->select('*', 'viewable_id', 'viewable_type', DB::raw('SUM(views) as view_count'))
69             ->groupBy('viewable_id', 'viewable_type')
70             ->orderBy('view_count', 'desc');
71
72         if ($filterModels) {
73             $query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
74         }
75
76         return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
77     }
78
79     /**
80      * Get all recently viewed entities for the current user.
81      * @param int $count
82      * @param int $page
83      * @param Entity|bool $filterModel
84      * @return mixed
85      */
86     public function getUserRecentlyViewed($count = 10, $page = 0, $filterModel = false)
87     {
88         $user = user();
89         if ($user === null || $user->isDefault()) {
90             return collect();
91         }
92
93         $query = $this->permissionService
94             ->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
95
96         if ($filterModel) {
97             $query = $query->where('viewable_type', '=', $filterModel->getMorphClass());
98         }
99         $query = $query->where('user_id', '=', $user->id);
100
101         $viewables = $query->with('viewable')->orderBy('updated_at', 'desc')
102             ->skip($count * $page)->take($count)->get()->pluck('viewable');
103         return $viewables;
104     }
105
106     /**
107      * Reset all view counts by deleting all views.
108      */
109     public function resetAll()
110     {
111         $this->view->truncate();
112     }
113 }