diff --git a/app/Auth/Permissions/PermissionService.php b/app/Auth/Permissions/PermissionService.php index 1c82f8e08..456598653 100644 --- a/app/Auth/Permissions/PermissionService.php +++ b/app/Auth/Permissions/PermissionService.php @@ -588,7 +588,7 @@ class PermissionService $q = $query->where(function ($query) use ($tableDetails, $action) { $query->whereExists(function ($permissionQuery) use (&$tableDetails, $action) { - $permissionQuery->select('id')->from('joint_permissions') + $permissionQuery->select(['role_id'])->from('joint_permissions') ->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn']) ->whereRaw('joint_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn']) ->where('action', '=', $action) diff --git a/app/Entities/Queries/TopFavourites.php b/app/Entities/Queries/TopFavourites.php index a527c2a4e..1434180d3 100644 --- a/app/Entities/Queries/TopFavourites.php +++ b/app/Entities/Queries/TopFavourites.php @@ -1,34 +1,33 @@ isDefault()) { + if (is_null($user) || $user->isDefault()) { return collect(); } $query = $this->permissionService() - ->filterRestrictedEntityRelations(View::query(), 'views', 'viewable_id', 'viewable_type', 'view') - ->select('*', 'viewable_id', 'viewable_type', DB::raw('SUM(views) as view_count')) - ->groupBy('viewable_id', 'viewable_type') - ->rightJoin('favourites', function (JoinClause $join) { - $join->on('views.viewable_id', '=', 'favourites.favouritable_id'); - $join->on('views.viewable_type', '=', 'favourites.favouritable_type'); - $join->where('favourites.user_id', '=', user()->id); + ->filterRestrictedEntityRelations(Favourite::query(), 'favourites', 'favouritable_id', 'favouritable_type', 'view') + ->select('favourites.*') + ->leftJoin('views', function (JoinClause $join) { + $join->on('favourites.favouritable_id', '=', 'views.viewable_id'); + $join->on('favourites.favouritable_type', '=', 'views.viewable_type'); + $join->where('views.user_id', '=', user()->id); }) - ->orderBy('view_count', 'desc'); + ->orderBy('views.views', 'desc') + ->where('favourites.user_id', '=', user()->id); - return $query->with('viewable') + return $query->with('favouritable') ->skip($skip) ->take($count) ->get() - ->pluck('viewable') + ->pluck('favouritable') ->filter(); } } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 1f77e6377..859857500 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -1,6 +1,5 @@ viewService = $viewService; $this->searchRunner = $searchRunner; $this->entityContextManager = $entityContextManager; } diff --git a/app/Providers/CustomFacadeProvider.php b/app/Providers/CustomFacadeProvider.php index f203f0fda..ca86b6607 100644 --- a/app/Providers/CustomFacadeProvider.php +++ b/app/Providers/CustomFacadeProvider.php @@ -3,7 +3,6 @@ namespace BookStack\Providers; use BookStack\Actions\ActivityService; -use BookStack\Actions\ViewService; use BookStack\Auth\Permissions\PermissionService; use BookStack\Theming\ThemeService; use BookStack\Uploads\ImageService; @@ -32,10 +31,6 @@ class CustomFacadeProvider extends ServiceProvider return $this->app->make(ActivityService::class); }); - $this->app->singleton('views', function () { - return $this->app->make(ViewService::class); - }); - $this->app->singleton('images', function () { return $this->app->make(ImageService::class); }); diff --git a/tests/FavouriteTest.php b/tests/FavouriteTest.php index ce5caf5c2..7209063c9 100644 --- a/tests/FavouriteTest.php +++ b/tests/FavouriteTest.php @@ -1,6 +1,9 @@ first(), + Book::query()->first(), + Chapter::query()->first(), + ]; + $this->actingAs($this->getEditor()); + + foreach ($entities as $entity) { + $resp = $this->get($entity->getUrl()); + $resp->assertElementExists('form[method="POST"][action$="/favourites/add"]'); + } + } + + public function test_header_contains_link_to_favourites_page_when_logged_in() + { + $this->setSettings(['app-public' => 'true']); + $this->get('/')->assertElementNotContains('header', 'My Favourites'); + $this->actingAs($this->getViewer())->get('/')->assertElementContains('header a', 'My Favourites'); + } + + public function test_favourites_shown_on_homepage() + { + $editor = $this->getEditor(); + + $resp = $this->actingAs($editor)->get('/'); + $resp->assertElementNotExists('#top-favourites'); + + /** @var Page $page */ + $page = Page::query()->first(); + $page->favourites()->save((new Favourite)->forceFill(['user_id' => $editor->id])); + + $resp = $this->get('/'); + $resp->assertElementExists('#top-favourites'); + $resp->assertElementContains('#top-favourites', $page->name); + } + + public function test_favourites_list_page_shows_favourites_and_has_working_pagination() + { + /** @var Page $page */ + $page = Page::query()->first(); + $editor = $this->getEditor(); + + $resp = $this->actingAs($editor)->get('/favourites'); + $resp->assertDontSee($page->name); + + $page->favourites()->save((new Favourite)->forceFill(['user_id' => $editor->id])); + + $resp = $this->get('/favourites'); + $resp->assertSee($page->name); + + $resp = $this->get('/favourites?page=2'); + $resp->assertDontSee($page->name); + } + } \ No newline at end of file