diff --git a/app/App/HomeController.php b/app/App/HomeController.php index dacd4bcc2..f5a3c7ed6 100644 --- a/app/App/HomeController.php +++ b/app/App/HomeController.php @@ -8,7 +8,6 @@ use BookStack\Entities\Models\Page; use BookStack\Entities\Queries\EntityQueries; use BookStack\Entities\Queries\RecentlyViewed; use BookStack\Entities\Queries\TopFavourites; -use BookStack\Entities\Repos\BookshelfRepo; use BookStack\Entities\Tools\PageContent; use BookStack\Http\Controller; use BookStack\Uploads\FaviconHandler; @@ -80,7 +79,9 @@ class HomeController extends Controller } if ($homepageOption === 'bookshelves') { - $shelves = app()->make(BookshelfRepo::class)->getAllPaginated(18, $commonData['listOptions']->getSort(), $commonData['listOptions']->getOrder()); + $shelves = $this->queries->shelves->visibleForListWithCover() + ->orderBy($commonData['listOptions']->getSort(), $commonData['listOptions']->getOrder()) + ->paginate(18); $data = array_merge($commonData, ['shelves' => $shelves]); return view('home.shelves', $data); diff --git a/app/Entities/Controllers/BookshelfController.php b/app/Entities/Controllers/BookshelfController.php index 2f5461cdb..bc3fc2a6f 100644 --- a/app/Entities/Controllers/BookshelfController.php +++ b/app/Entities/Controllers/BookshelfController.php @@ -5,6 +5,7 @@ namespace BookStack\Entities\Controllers; use BookStack\Activity\ActivityQueries; use BookStack\Activity\Models\View; use BookStack\Entities\Models\Book; +use BookStack\Entities\Queries\BookshelfQueries; use BookStack\Entities\Repos\BookshelfRepo; use BookStack\Entities\Tools\ShelfContext; use BookStack\Exceptions\ImageUploadException; @@ -20,8 +21,9 @@ class BookshelfController extends Controller { public function __construct( protected BookshelfRepo $shelfRepo, + protected BookshelfQueries $queries, protected ShelfContext $shelfContext, - protected ReferenceFetcher $referenceFetcher + protected ReferenceFetcher $referenceFetcher, ) { } @@ -37,10 +39,15 @@ class BookshelfController extends Controller 'updated_at' => trans('common.sort_updated_at'), ]); - $shelves = $this->shelfRepo->getAllPaginated(18, $listOptions->getSort(), $listOptions->getOrder()); - $recents = $this->isSignedIn() ? $this->shelfRepo->getRecentlyViewed(4) : false; - $popular = $this->shelfRepo->getPopular(4); - $new = $this->shelfRepo->getRecentlyCreated(4); + $shelves = $this->queries->visibleForListWithCover() + ->orderBy($listOptions->getSort(), $listOptions->getOrder()) + ->paginate(18); + $recents = $this->isSignedIn() ? $this->queries->recentlyViewedForCurrentUser()->get() : false; + $popular = $this->queries->popularForList()->get(); + $new = $this->queries->visibleForList() + ->orderBy('created_at', 'desc') + ->take(4) + ->get(); $this->shelfContext->clearShelfContext(); $this->setPageTitle(trans('entities.shelves')); @@ -96,7 +103,7 @@ class BookshelfController extends Controller */ public function show(Request $request, ActivityQueries $activities, string $slug) { - $shelf = $this->shelfRepo->getBySlug($slug); + $shelf = $this->queries->findVisibleBySlug($slug); $this->checkOwnablePermission('bookshelf-view', $shelf); $listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([ @@ -134,7 +141,7 @@ class BookshelfController extends Controller */ public function edit(string $slug) { - $shelf = $this->shelfRepo->getBySlug($slug); + $shelf = $this->queries->findVisibleBySlug($slug); $this->checkOwnablePermission('bookshelf-update', $shelf); $shelfBookIds = $shelf->books()->get(['id'])->pluck('id'); @@ -157,7 +164,7 @@ class BookshelfController extends Controller */ public function update(Request $request, string $slug) { - $shelf = $this->shelfRepo->getBySlug($slug); + $shelf = $this->queries->findVisibleBySlug($slug); $this->checkOwnablePermission('bookshelf-update', $shelf); $validated = $this->validate($request, [ 'name' => ['required', 'string', 'max:255'], @@ -183,7 +190,7 @@ class BookshelfController extends Controller */ public function showDelete(string $slug) { - $shelf = $this->shelfRepo->getBySlug($slug); + $shelf = $this->queries->findVisibleBySlug($slug); $this->checkOwnablePermission('bookshelf-delete', $shelf); $this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()])); @@ -198,7 +205,7 @@ class BookshelfController extends Controller */ public function destroy(string $slug) { - $shelf = $this->shelfRepo->getBySlug($slug); + $shelf = $this->queries->findVisibleBySlug($slug); $this->checkOwnablePermission('bookshelf-delete', $shelf); $this->shelfRepo->destroy($shelf); diff --git a/app/Entities/Queries/BookshelfQueries.php b/app/Entities/Queries/BookshelfQueries.php new file mode 100644 index 000000000..7edff45b9 --- /dev/null +++ b/app/Entities/Queries/BookshelfQueries.php @@ -0,0 +1,56 @@ +start() + ->scopes('visible') + ->where('slug', '=', $slug) + ->first(); + + if ($shelf === null) { + throw new NotFoundException(trans('errors.bookshelf_not_found')); + } + + return $shelf; + } + + public function visibleForList(): Builder + { + return $this->start()->scopes('visible'); + } + + public function visibleForListWithCover(): Builder + { + return $this->visibleForList()->with('cover'); + } + + public function recentlyViewedForCurrentUser(): Builder + { + return $this->visibleForList() + ->scopes('withLastView') + ->having('last_viewed_at', '>', 0) + ->orderBy('last_viewed_at', 'desc'); + } + + public function popularForList(): Builder + { + return $this->visibleForList() + ->scopes('withViewCount') + ->having('view_count', '>', 0) + ->orderBy('view_count', 'desc'); + } +} diff --git a/app/Entities/Queries/EntityQueries.php b/app/Entities/Queries/EntityQueries.php index 417db455c..b1973b0ea 100644 --- a/app/Entities/Queries/EntityQueries.php +++ b/app/Entities/Queries/EntityQueries.php @@ -5,6 +5,7 @@ namespace BookStack\Entities\Queries; class EntityQueries { public function __construct( + public BookshelfQueries $shelves, public BookQueries $books, public PageQueries $pages, ) { diff --git a/app/Entities/Repos/BookshelfRepo.php b/app/Entities/Repos/BookshelfRepo.php index 27333b5b1..479e6178f 100644 --- a/app/Entities/Repos/BookshelfRepo.php +++ b/app/Entities/Repos/BookshelfRepo.php @@ -6,78 +6,14 @@ use BookStack\Activity\ActivityType; use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Tools\TrashCan; -use BookStack\Exceptions\NotFoundException; use BookStack\Facades\Activity; use Exception; -use Illuminate\Contracts\Pagination\LengthAwarePaginator; -use Illuminate\Support\Collection; class BookshelfRepo { - protected $baseRepo; - - /** - * BookshelfRepo constructor. - */ - public function __construct(BaseRepo $baseRepo) - { - $this->baseRepo = $baseRepo; - } - - /** - * Get all bookshelves in a paginated format. - */ - public function getAllPaginated(int $count = 20, string $sort = 'name', string $order = 'asc'): LengthAwarePaginator - { - return Bookshelf::visible() - ->with(['visibleBooks', 'cover']) - ->orderBy($sort, $order) - ->paginate($count); - } - - /** - * Get the bookshelves that were most recently viewed by this user. - */ - public function getRecentlyViewed(int $count = 20): Collection - { - return Bookshelf::visible()->withLastView() - ->having('last_viewed_at', '>', 0) - ->orderBy('last_viewed_at', 'desc') - ->take($count)->get(); - } - - /** - * Get the most popular bookshelves in the system. - */ - public function getPopular(int $count = 20): Collection - { - return Bookshelf::visible()->withViewCount() - ->having('view_count', '>', 0) - ->orderBy('view_count', 'desc') - ->take($count)->get(); - } - - /** - * Get the most recently created bookshelves from the system. - */ - public function getRecentlyCreated(int $count = 20): Collection - { - return Bookshelf::visible()->orderBy('created_at', 'desc') - ->take($count)->get(); - } - - /** - * Get a shelf by its slug. - */ - public function getBySlug(string $slug): Bookshelf - { - $shelf = Bookshelf::visible()->where('slug', '=', $slug)->first(); - - if ($shelf === null) { - throw new NotFoundException(trans('errors.bookshelf_not_found')); - } - - return $shelf; + public function __construct( + protected BaseRepo $baseRepo, + ) { } /**