]> BookStack Code Mirror - bookstack/blob - app/Actions/ViewService.php
Started building system for cross-model queries
[bookstack] / app / Actions / ViewService.php
1 <?php namespace BookStack\Actions;
2
3 use BookStack\Auth\Permissions\PermissionService;
4 use BookStack\Entities\Models\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      * Get the entities with the most views.
30      * @param int $count
31      * @param int $page
32      * @param string|array $filterModels
33      * @param string $action - used for permission checking
34      * @return Collection
35      */
36     public function getPopular(int $count = 10, int $page = 0, array $filterModels = null, string $action = 'view')
37     {
38         $skipCount = $count * $page;
39         $query = $this->permissionService
40             ->filterRestrictedEntityRelations($this->view->newQuery(), 'views', 'viewable_id', 'viewable_type', $action)
41             ->select('*', 'viewable_id', 'viewable_type', DB::raw('SUM(views) as view_count'))
42             ->groupBy('viewable_id', 'viewable_type')
43             ->orderBy('view_count', 'desc');
44
45         if ($filterModels) {
46             $query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
47         }
48
49         return $query->with('viewable')
50             ->skip($skipCount)
51             ->take($count)
52             ->get()
53             ->pluck('viewable')
54             ->filter();
55     }
56
57     /**
58      * Get all recently viewed entities for the current user.
59      */
60     public function getUserRecentlyViewed(int $count = 10, int $page = 1)
61     {
62         $user = user();
63         if ($user === null || $user->isDefault()) {
64             return collect();
65         }
66
67         $all = collect();
68         /** @var Entity $instance */
69         foreach ($this->entityProvider->all() as $name => $instance) {
70             $items = $instance::visible()->withLastView()
71                 ->having('last_viewed_at', '>', 0)
72                 ->orderBy('last_viewed_at', 'desc')
73                 ->skip($count * ($page - 1))
74                 ->take($count)
75                 ->get();
76             $all = $all->concat($items);
77         }
78
79         return $all->sortByDesc('last_viewed_at')->slice(0, $count);
80     }
81 }