]> BookStack Code Mirror - bookstack/commitdiff
Queries: Updated all app book static query uses
authorDan Brown <redacted>
Wed, 7 Feb 2024 16:37:36 +0000 (16:37 +0000)
committerDan Brown <redacted>
Wed, 7 Feb 2024 16:37:36 +0000 (16:37 +0000)
37 files changed:
app/App/HomeController.php
app/Entities/Controllers/BookApiController.php
app/Entities/Controllers/BookExportApiController.php
app/Entities/Controllers/BookshelfController.php
app/Entities/Controllers/ChapterApiController.php
app/Entities/Controllers/PageApiController.php
app/Entities/Controllers/PageController.php
app/Entities/Controllers/RecycleBinController.php
app/Entities/Models/Book.php
app/Entities/Queries/BookQueries.php
app/Entities/Queries/ChapterQueries.php
app/Entities/Queries/PageQueries.php
app/Entities/Repos/BookRepo.php
app/Entities/Repos/BookshelfRepo.php
app/Entities/Repos/ChapterRepo.php
app/Entities/Repos/PageRepo.php
app/Entities/Tools/BookContents.php
app/Entities/Tools/Cloner.php
app/Entities/Tools/SiblingFetcher.php
app/Entities/Tools/TrashCan.php
app/Permissions/JointPermissionBuilder.php
app/Permissions/PermissionsController.php
app/References/CrossLinkParser.php
app/References/ModelResolvers/BookLinkModelResolver.php
app/References/ModelResolvers/BookshelfLinkModelResolver.php
app/References/ModelResolvers/ChapterLinkModelResolver.php
app/References/ModelResolvers/PageLinkModelResolver.php
app/References/ModelResolvers/PagePermalinkModelResolver.php
app/References/ReferenceController.php
app/Search/SearchController.php
app/Settings/MaintenanceController.php
app/Uploads/ImageService.php
app/Users/Controllers/UserProfileController.php
app/Users/Queries/UserContentCounts.php
app/Users/Queries/UserRecentlyCreatedContent.php
tests/Entity/BookTest.php
tests/Entity/EntitySearchTest.php

index f5a3c7ed6cb396efb4796c7fd96fd95e18eefe87..6a4cb017669225e92c1467d59c0e0c273c191b52 100644 (file)
@@ -40,7 +40,7 @@ class HomeController extends Controller
         $recentFactor = count($draftPages) > 0 ? 0.5 : 1;
         $recents = $this->isSignedIn() ?
             (new RecentlyViewed())->run(12 * $recentFactor, 1)
-            : Book::visible()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get();
+            : $this->queries->books->visibleForList()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get();
         $favourites = (new TopFavourites())->run(6);
         $recentlyUpdatedPages = $this->queries->pages->visibleForList()
             ->where('draft', false)
index aa21aea472a8d044d718cb1d04d0e4745e0a7115..955bd707bc6f5ceeb84440a71742b24fcf6dc549 100644 (file)
@@ -6,6 +6,7 @@ use BookStack\Api\ApiEntityListFormatter;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Queries\BookQueries;
 use BookStack\Entities\Repos\BookRepo;
 use BookStack\Entities\Tools\BookContents;
 use BookStack\Http\ApiController;
@@ -15,7 +16,8 @@ use Illuminate\Validation\ValidationException;
 class BookApiController extends ApiController
 {
     public function __construct(
-        protected BookRepo $bookRepo
+        protected BookRepo $bookRepo,
+        protected BookQueries $queries,
     ) {
     }
 
@@ -24,7 +26,7 @@ class BookApiController extends ApiController
      */
     public function list()
     {
-        $books = Book::visible();
+        $books = $this->queries->visibleForList();
 
         return $this->apiListingResponse($books, [
             'id', 'name', 'slug', 'description', 'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by',
@@ -56,7 +58,7 @@ class BookApiController extends ApiController
      */
     public function read(string $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail(intval($id));
         $book = $this->forJsonDisplay($book);
         $book->load(['createdBy', 'updatedBy', 'ownedBy']);
 
@@ -83,7 +85,7 @@ class BookApiController extends ApiController
      */
     public function update(Request $request, string $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail(intval($id));
         $this->checkOwnablePermission('book-update', $book);
 
         $requestData = $this->validate($request, $this->rules()['update']);
@@ -100,7 +102,7 @@ class BookApiController extends ApiController
      */
     public function delete(string $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail(intval($id));
         $this->checkOwnablePermission('book-delete', $book);
 
         $this->bookRepo->destroy($book);
index 5b6826c193dcb9f40b8abca33d2d4ab439c1e848..1161ddb8886964423f088630424317225914eb74 100644 (file)
@@ -2,18 +2,17 @@
 
 namespace BookStack\Entities\Controllers;
 
-use BookStack\Entities\Models\Book;
+use BookStack\Entities\Queries\BookQueries;
 use BookStack\Entities\Tools\ExportFormatter;
 use BookStack\Http\ApiController;
 use Throwable;
 
 class BookExportApiController extends ApiController
 {
-    protected $exportFormatter;
-
-    public function __construct(ExportFormatter $exportFormatter)
-    {
-        $this->exportFormatter = $exportFormatter;
+    public function __construct(
+        protected ExportFormatter $exportFormatter,
+        protected BookQueries $queries,
+    ) {
         $this->middleware('can:content-export');
     }
 
@@ -24,7 +23,7 @@ class BookExportApiController extends ApiController
      */
     public function exportPdf(int $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail($id);
         $pdfContent = $this->exportFormatter->bookToPdf($book);
 
         return $this->download()->directly($pdfContent, $book->slug . '.pdf');
@@ -37,7 +36,7 @@ class BookExportApiController extends ApiController
      */
     public function exportHtml(int $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail($id);
         $htmlContent = $this->exportFormatter->bookToContainedHtml($book);
 
         return $this->download()->directly($htmlContent, $book->slug . '.html');
@@ -48,7 +47,7 @@ class BookExportApiController extends ApiController
      */
     public function exportPlainText(int $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail($id);
         $textContent = $this->exportFormatter->bookToPlainText($book);
 
         return $this->download()->directly($textContent, $book->slug . '.txt');
@@ -59,7 +58,7 @@ class BookExportApiController extends ApiController
      */
     public function exportMarkdown(int $id)
     {
-        $book = Book::visible()->findOrFail($id);
+        $book = $this->queries->findVisibleByIdOrFail($id);
         $markdown = $this->exportFormatter->bookToMarkdown($book);
 
         return $this->download()->directly($markdown, $book->slug . '.md');
index 3118325da00597a5db06f0c417b66674118fb2b3..6cedd23e7df244d35e74591d04297a95a761cff8 100644 (file)
@@ -4,7 +4,7 @@ namespace BookStack\Entities\Controllers;
 
 use BookStack\Activity\ActivityQueries;
 use BookStack\Activity\Models\View;
-use BookStack\Entities\Models\Book;
+use BookStack\Entities\Queries\BookQueries;
 use BookStack\Entities\Queries\BookshelfQueries;
 use BookStack\Entities\Repos\BookshelfRepo;
 use BookStack\Entities\Tools\ShelfContext;
@@ -22,6 +22,7 @@ class BookshelfController extends Controller
     public function __construct(
         protected BookshelfRepo $shelfRepo,
         protected BookshelfQueries $queries,
+        protected BookQueries $bookQueries,
         protected ShelfContext $shelfContext,
         protected ReferenceFetcher $referenceFetcher,
     ) {
@@ -68,7 +69,7 @@ class BookshelfController extends Controller
     public function create()
     {
         $this->checkPermission('bookshelf-create-all');
-        $books = Book::visible()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
+        $books = $this->bookQueries->visibleForList()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
         $this->setPageTitle(trans('entities.shelves_create'));
 
         return view('shelves.create', ['books' => $books]);
@@ -145,7 +146,10 @@ class BookshelfController extends Controller
         $this->checkOwnablePermission('bookshelf-update', $shelf);
 
         $shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
-        $books = Book::visible()->whereNotIn('id', $shelfBookIds)->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
+        $books = $this->bookQueries->visibleForList()
+            ->whereNotIn('id', $shelfBookIds)
+            ->orderBy('name')
+            ->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
 
         $this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $shelf->getShortName()]));
 
index 3fbe852220579d2b0ad36b8b7f3237d5338af658..fb484b85d72db13ae35f0eaca97de7388b026b35 100644 (file)
@@ -2,8 +2,9 @@
 
 namespace BookStack\Entities\Controllers;
 
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Chapter;
+use BookStack\Entities\Queries\BookQueries;
+use BookStack\Entities\Queries\ChapterQueries;
 use BookStack\Entities\Repos\ChapterRepo;
 use BookStack\Exceptions\PermissionsException;
 use BookStack\Http\ApiController;
@@ -35,7 +36,9 @@ class ChapterApiController extends ApiController
     ];
 
     public function __construct(
-        protected ChapterRepo $chapterRepo
+        protected ChapterRepo $chapterRepo,
+        protected ChapterQueries $queries,
+        protected BookQueries $bookQueries,
     ) {
     }
 
@@ -44,7 +47,7 @@ class ChapterApiController extends ApiController
      */
     public function list()
     {
-        $chapters = Chapter::visible();
+        $chapters = $this->queries->visibleForList();
 
         return $this->apiListingResponse($chapters, [
             'id', 'book_id', 'name', 'slug', 'description', 'priority',
@@ -60,7 +63,7 @@ class ChapterApiController extends ApiController
         $requestData = $this->validate($request, $this->rules['create']);
 
         $bookId = $request->get('book_id');
-        $book = Book::visible()->findOrFail($bookId);
+        $book = $this->bookQueries->findVisibleByIdOrFail(intval($bookId));
         $this->checkOwnablePermission('chapter-create', $book);
 
         $chapter = $this->chapterRepo->create($requestData, $book);
@@ -73,7 +76,7 @@ class ChapterApiController extends ApiController
      */
     public function read(string $id)
     {
-        $chapter = Chapter::visible()->findOrFail($id);
+        $chapter = $this->queries->findVisibleByIdOrFail(intval($id));
         $chapter = $this->forJsonDisplay($chapter);
 
         $chapter->load([
@@ -94,7 +97,7 @@ class ChapterApiController extends ApiController
     public function update(Request $request, string $id)
     {
         $requestData = $this->validate($request, $this->rules()['update']);
-        $chapter = Chapter::visible()->findOrFail($id);
+        $chapter = $this->queries->findVisibleByIdOrFail(intval($id));
         $this->checkOwnablePermission('chapter-update', $chapter);
 
         if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) {
@@ -122,7 +125,7 @@ class ChapterApiController extends ApiController
      */
     public function delete(string $id)
     {
-        $chapter = Chapter::visible()->findOrFail($id);
+        $chapter = $this->queries->findVisibleByIdOrFail(intval($id));
         $this->checkOwnablePermission('chapter-delete', $chapter);
 
         $this->chapterRepo->destroy($chapter);
index 6e3880aedc4294f904993e91e3e89561f7584a4c..d2a5a3ee3514416d2d9df9611a9f1d901134a1be 100644 (file)
@@ -2,9 +2,7 @@
 
 namespace BookStack\Entities\Controllers;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Entities\Queries\PageQueries;
 use BookStack\Entities\Repos\PageRepo;
 use BookStack\Exceptions\PermissionsException;
@@ -38,6 +36,7 @@ class PageApiController extends ApiController
     public function __construct(
         protected PageRepo $pageRepo,
         protected PageQueries $queries,
+        protected EntityQueries $entityQueries,
     ) {
     }
 
@@ -46,7 +45,7 @@ class PageApiController extends ApiController
      */
     public function list()
     {
-        $pages = Page::visible();
+        $pages = $this->queries->visibleForList();
 
         return $this->apiListingResponse($pages, [
             'id', 'book_id', 'chapter_id', 'name', 'slug', 'priority',
@@ -72,9 +71,9 @@ class PageApiController extends ApiController
         $this->validate($request, $this->rules['create']);
 
         if ($request->has('chapter_id')) {
-            $parent = Chapter::visible()->findOrFail($request->get('chapter_id'));
+            $parent = $this->entityQueries->chapters->findVisibleByIdOrFail(intval($request->get('chapter_id')));
         } else {
-            $parent = Book::visible()->findOrFail($request->get('book_id'));
+            $parent = $this->entityQueries->books->findVisibleByIdOrFail(intval($request->get('book_id')));
         }
         $this->checkOwnablePermission('page-create', $parent);
 
@@ -120,9 +119,9 @@ class PageApiController extends ApiController
 
         $parent = null;
         if ($request->has('chapter_id')) {
-            $parent = Chapter::visible()->findOrFail($request->get('chapter_id'));
+            $parent = $this->entityQueries->chapters->findVisibleByIdOrFail(intval($request->get('chapter_id')));
         } elseif ($request->has('book_id')) {
-            $parent = Book::visible()->findOrFail($request->get('book_id'));
+            $parent = $this->entityQueries->books->findVisibleByIdOrFail(intval($request->get('book_id')));
         }
 
         if ($parent && !$parent->matches($page->getParent())) {
index 3a5bdbd0bf134012224f24db39941aae499b10e6..471df8184ba468bacac054547271d264e19ccc48 100644 (file)
@@ -276,8 +276,8 @@ class PageController extends Controller
         $this->checkOwnablePermission('page-delete', $page);
         $this->setPageTitle(trans('entities.pages_delete_named', ['pageName' => $page->getShortName()]));
         $usedAsTemplate =
-            Book::query()->where('default_template_id', '=', $page->id)->count() > 0 ||
-            Chapter::query()->where('default_template_id', '=', $page->id)->count() > 0;
+            $this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
+            $this->entityQueries->chapters->start()->where('default_template_id', '=', $page->id)->count() > 0;
 
         return view('pages.delete', [
             'book'    => $page->book,
@@ -298,8 +298,8 @@ class PageController extends Controller
         $this->checkOwnablePermission('page-update', $page);
         $this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()]));
         $usedAsTemplate =
-            Book::query()->where('default_template_id', '=', $page->id)->count() > 0 ||
-            Chapter::query()->where('default_template_id', '=', $page->id)->count() > 0;
+            $this->entityQueries->books->start()->where('default_template_id', '=', $page->id)->count() > 0 ||
+            $this->entityQueries->chapters->start()->where('default_template_id', '=', $page->id)->count() > 0;
 
         return view('pages.delete', [
             'book'    => $page->book,
index 78f86a5ae5076df7c5cea7320b2c25fc657a121b..d11dde4dd73b19d39bb756076ef4d2c511ba26c5 100644 (file)
@@ -116,9 +116,9 @@ class RecycleBinController extends Controller
      *
      * @throws \Exception
      */
-    public function empty()
+    public function empty(TrashCan $trash)
     {
-        $deleteCount = (new TrashCan())->empty();
+        $deleteCount = $trash->empty();
 
         $this->logActivity(ActivityType::RECYCLE_BIN_EMPTY);
         $this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
index 14cb790c5c509c9283713aaa6a1b69fce4f22b8b..c1644dcf5fb10afa03ebff7d38142e5162785c9d 100644 (file)
@@ -117,20 +117,11 @@ class Book extends Entity implements HasCoverImage
     /**
      * Get the direct child items within this book.
      */
-    public function getDirectChildren(): Collection
+    public function getDirectVisibleChildren(): Collection
     {
         $pages = $this->directPages()->scopes('visible')->get();
         $chapters = $this->chapters()->scopes('visible')->get();
 
         return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
     }
-
-    /**
-     * Get a visible book by its slug.
-     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
-     */
-    public static function getBySlug(string $slug): self
-    {
-        return static::visible()->where('slug', '=', $slug)->firstOrFail();
-    }
 }
index 3d7474b3dfab6e9e9d22bda6154464c4999f326d..2ffff5eca2e95fe11103bff719ca39c1ad554917 100644 (file)
@@ -18,6 +18,11 @@ class BookQueries implements ProvidesEntityQueries
         return $this->start()->scopes('visible')->find($id);
     }
 
+    public function findVisibleByIdOrFail(int $id): Book
+    {
+        return $this->start()->scopes('visible')->findOrFail($id);
+    }
+
     public function findVisibleBySlugOrFail(string $slug): Book
     {
         /** @var ?Book $book */
index 200514932cd186cd470bf11a47941d8fe925c0a9..31193c7ea73db33490e1b1dd2c33d0cb6ed7ce2a 100644 (file)
@@ -24,10 +24,17 @@ class ChapterQueries implements ProvidesEntityQueries
         return $this->start()->scopes('visible')->find($id);
     }
 
+    public function findVisibleByIdOrFail(int $id): Chapter
+    {
+        return $this->start()->scopes('visible')->findOrFail($id);
+    }
+
     public function findVisibleBySlugsOrFail(string $bookSlug, string $chapterSlug): Chapter
     {
         /** @var ?Chapter $chapter */
-        $chapter = $this->start()->with('book')
+        $chapter = $this->start()
+            ->scopes('visible')
+            ->with('book')
             ->whereHas('book', function (Builder $query) use ($bookSlug) {
                 $query->where('slug', '=', $bookSlug);
             })
@@ -41,9 +48,19 @@ class ChapterQueries implements ProvidesEntityQueries
         return $chapter;
     }
 
+    public function usingSlugs(string $bookSlug, string $chapterSlug): Builder
+    {
+        return $this->start()
+            ->where('slug', '=', $chapterSlug)
+            ->whereHas('book', function (Builder $query) use ($bookSlug) {
+                $query->where('slug', '=', $bookSlug);
+            });
+    }
+
     public function visibleForList(): Builder
     {
         return $this->start()
+            ->scopes('visible')
             ->select(array_merge(static::$listAttributes, ['book_slug' => function ($builder) {
                 $builder->select('slug')
                     ->from('books')
index 1640dc2db54b32d0cd6f0b70c9461f867c729fc4..e22769c3af6915b9ae601708dcf74d3826dcd322 100644 (file)
@@ -33,6 +33,7 @@ class PageQueries implements ProvidesEntityQueries
     {
         /** @var ?Page $page */
         $page = $this->start()->with('book')
+            ->scopes('visible')
             ->whereHas('book', function (Builder $query) use ($bookSlug) {
                 $query->where('slug', '=', $bookSlug);
             })
@@ -46,9 +47,19 @@ class PageQueries implements ProvidesEntityQueries
         return $page;
     }
 
+    public function usingSlugs(string $bookSlug, string $pageSlug): Builder
+    {
+        return $this->start()
+            ->where('slug', '=', $pageSlug)
+            ->whereHas('book', function (Builder $query) use ($bookSlug) {
+                $query->where('slug', '=', $bookSlug);
+            });
+    }
+
     public function visibleForList(): Builder
     {
         return $this->start()
+            ->scopes('visible')
             ->select(array_merge(Page::$listAttributes, ['book_slug' => function ($builder) {
                 $builder->select('slug')
                     ->from('books')
@@ -56,6 +67,17 @@ class PageQueries implements ProvidesEntityQueries
             }]));
     }
 
+    public function visibleWithContents(): Builder
+    {
+        return $this->start()
+            ->scopes('visible')
+            ->select(array_merge(Page::$contentAttributes, ['book_slug' => function ($builder) {
+                $builder->select('slug')
+                    ->from('books')
+                    ->whereColumn('books.id', '=', 'pages.book_id');
+            }]));
+    }
+
     public function currentUserDraftsForList(): Builder
     {
         return $this->visibleForList()
index 26b9414fbac24ebd74cb7db1d9d604e422029a42..19d159eb1e7e9cc539a86f6031ef8004a20e70ef 100644 (file)
@@ -17,7 +17,8 @@ class BookRepo
     public function __construct(
         protected BaseRepo $baseRepo,
         protected TagRepo $tagRepo,
-        protected ImageRepo $imageRepo
+        protected ImageRepo $imageRepo,
+        protected TrashCan $trashCan,
     ) {
     }
 
@@ -73,10 +74,9 @@ class BookRepo
      */
     public function destroy(Book $book)
     {
-        $trashCan = new TrashCan();
-        $trashCan->softDestroyBook($book);
+        $this->trashCan->softDestroyBook($book);
         Activity::add(ActivityType::BOOK_DELETE, $book);
 
-        $trashCan->autoClearOld();
+        $this->trashCan->autoClearOld();
     }
 }
index 479e6178f7b73d151f779e41a913825c11b35407..a00349ef1aeaec8cc79949932e4132ea14bc8d73 100644 (file)
@@ -3,8 +3,8 @@
 namespace BookStack\Entities\Repos;
 
 use BookStack\Activity\ActivityType;
-use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Bookshelf;
+use BookStack\Entities\Queries\BookQueries;
 use BookStack\Entities\Tools\TrashCan;
 use BookStack\Facades\Activity;
 use Exception;
@@ -13,6 +13,8 @@ class BookshelfRepo
 {
     public function __construct(
         protected BaseRepo $baseRepo,
+        protected BookQueries $bookQueries,
+        protected TrashCan $trashCan,
     ) {
     }
 
@@ -60,7 +62,7 @@ class BookshelfRepo
             return intval($id);
         });
 
-        $syncData = Book::visible()
+        $syncData = $this->bookQueries->visibleForList()
             ->whereIn('id', $bookIds)
             ->pluck('id')
             ->mapWithKeys(function ($bookId) use ($numericIDs) {
@@ -77,9 +79,8 @@ class BookshelfRepo
      */
     public function destroy(Bookshelf $shelf)
     {
-        $trashCan = new TrashCan();
-        $trashCan->softDestroyShelf($shelf);
+        $this->trashCan->softDestroyShelf($shelf);
         Activity::add(ActivityType::BOOKSHELF_DELETE, $shelf);
-        $trashCan->autoClearOld();
+        $this->trashCan->autoClearOld();
     }
 }
index cacca93f6e9f2968ee22fe57969b3bff61e5003a..17cbccd4133676bc44aac8aaf844478ba771e5c7 100644 (file)
@@ -18,6 +18,7 @@ class ChapterRepo
     public function __construct(
         protected BaseRepo $baseRepo,
         protected EntityQueries $entityQueries,
+        protected TrashCan $trashCan,
     ) {
     }
 
@@ -59,10 +60,9 @@ class ChapterRepo
      */
     public function destroy(Chapter $chapter)
     {
-        $trashCan = new TrashCan();
-        $trashCan->softDestroyChapter($chapter);
+        $this->trashCan->softDestroyChapter($chapter);
         Activity::add(ActivityType::CHAPTER_DELETE, $chapter);
-        $trashCan->autoClearOld();
+        $this->trashCan->autoClearOld();
     }
 
     /**
index 74aed072a0657f5c7494a4838f8ca9970ea7cdf0..2526b6c445d168757db794b875c5ce6263a37cc3 100644 (file)
@@ -27,7 +27,8 @@ class PageRepo
         protected RevisionRepo $revisionRepo,
         protected EntityQueries $entityQueries,
         protected ReferenceStore $referenceStore,
-        protected ReferenceUpdater $referenceUpdater
+        protected ReferenceUpdater $referenceUpdater,
+        protected TrashCan $trashCan,
     ) {
     }
 
@@ -184,10 +185,9 @@ class PageRepo
      */
     public function destroy(Page $page)
     {
-        $trashCan = new TrashCan();
-        $trashCan->softDestroyPage($page);
+        $this->trashCan->softDestroyPage($page);
         Activity::add(ActivityType::PAGE_DELETE, $page);
-        $trashCan->autoClearOld();
+        $this->trashCan->autoClearOld();
     }
 
     /**
index f45bdfcc1b98fabcdb2d4dc774c30752a7582ef1..7fa2134b7fad60627393c334781d512542133298 100644 (file)
@@ -7,15 +7,17 @@ use BookStack\Entities\Models\BookChild;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use Illuminate\Support\Collection;
 
 class BookContents
 {
-    protected Book $book;
+    protected EntityQueries $queries;
 
-    public function __construct(Book $book)
-    {
-        $this->book = $book;
+    public function __construct(
+        protected Book $book,
+    ) {
+        $this->queries = app()->make(EntityQueries::class);
     }
 
     /**
@@ -23,10 +25,12 @@ class BookContents
      */
     public function getLastPriority(): int
     {
-        $maxPage = Page::visible()->where('book_id', '=', $this->book->id)
+        $maxPage = $this->book->pages()
             ->where('draft', '=', false)
-            ->where('chapter_id', '=', 0)->max('priority');
-        $maxChapter = Chapter::visible()->where('book_id', '=', $this->book->id)
+            ->where('chapter_id', '=', 0)
+            ->max('priority');
+
+        $maxChapter = $this->book->chapters()
             ->max('priority');
 
         return max($maxChapter, $maxPage, 1);
@@ -38,7 +42,7 @@ class BookContents
     public function getTree(bool $showDrafts = false, bool $renderPages = false): Collection
     {
         $pages = $this->getPages($showDrafts, $renderPages);
-        $chapters = Chapter::visible()->where('book_id', '=', $this->book->id)->get();
+        $chapters = $this->book->chapters()->scopes('visible')->get();
         $all = collect()->concat($pages)->concat($chapters);
         $chapterMap = $chapters->keyBy('id');
         $lonePages = collect();
@@ -87,15 +91,17 @@ class BookContents
      */
     protected function getPages(bool $showDrafts = false, bool $getPageContent = false): Collection
     {
-        $query = Page::visible()
-            ->select($getPageContent ? Page::$contentAttributes : Page::$listAttributes)
-            ->where('book_id', '=', $this->book->id);
+        if ($getPageContent) {
+            $query = $this->queries->pages->visibleWithContents();
+        } else {
+            $query = $this->queries->pages->visibleForList();
+        }
 
         if (!$showDrafts) {
             $query->where('draft', '=', false);
         }
 
-        return $query->get();
+        return $query->where('book_id', '=', $this->book->id)->get();
     }
 
     /**
@@ -126,7 +132,7 @@ class BookContents
 
         /** @var Book[] $booksInvolved */
         $booksInvolved = array_values(array_filter($modelMap, function (string $key) {
-            return strpos($key, 'book:') === 0;
+            return str_starts_with($key, 'book:');
         }, ARRAY_FILTER_USE_KEY));
 
         // Update permissions of books involved
@@ -279,7 +285,7 @@ class BookContents
             }
         }
 
-        $pages = Page::visible()->whereIn('id', array_unique($ids['page']))->get(Page::$listAttributes);
+        $pages = $this->queries->pages->visibleForList()->whereIn('id', array_unique($ids['page']))->get();
         /** @var Page $page */
         foreach ($pages as $page) {
             $modelMap['page:' . $page->id] = $page;
@@ -289,14 +295,14 @@ class BookContents
             }
         }
 
-        $chapters = Chapter::visible()->whereIn('id', array_unique($ids['chapter']))->get();
+        $chapters = $this->queries->chapters->visibleForList()->whereIn('id', array_unique($ids['chapter']))->get();
         /** @var Chapter $chapter */
         foreach ($chapters as $chapter) {
             $modelMap['chapter:' . $chapter->id] = $chapter;
             $ids['book'][] = $chapter->book_id;
         }
 
-        $books = Book::visible()->whereIn('id', array_unique($ids['book']))->get();
+        $books = $this->queries->books->visibleForList()->whereIn('id', array_unique($ids['book']))->get();
         /** @var Book $book */
         foreach ($books as $book) {
             $modelMap['book:' . $book->id] = $book;
index f7ed4b72dcb628263b5ce0395ea29d4bd440ff59..2030b050c4b19f39e01b1c6312c3e381405ff855 100644 (file)
@@ -77,7 +77,7 @@ class Cloner
         $copyBook = $this->bookRepo->create($bookDetails);
 
         // Clone contents
-        $directChildren = $original->getDirectChildren();
+        $directChildren = $original->getDirectVisibleChildren();
         foreach ($directChildren as $child) {
             if ($child instanceof Chapter && userCan('chapter-create', $copyBook)) {
                 $this->cloneChapter($child, $copyBook, $child->name);
index 617ef4a620df810f9369e8fd8f6e49abed461304..7b8ac37ad8792429038bb9645355488d4dbcf853 100644 (file)
@@ -7,10 +7,16 @@ use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Bookshelf;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use Illuminate\Support\Collection;
 
 class SiblingFetcher
 {
+    public function __construct(
+        protected EntityQueries $queries,
+    ) {
+    }
+
     /**
      * Search among the siblings of the entity of given type and id.
      */
@@ -26,7 +32,7 @@ class SiblingFetcher
 
         // Page in book or chapter
         if (($entity instanceof Page && !$entity->chapter) || $entity instanceof Chapter) {
-            $entities = $entity->book->getDirectChildren();
+            $entities = $entity->book->getDirectVisibleChildren();
         }
 
         // Book
@@ -36,13 +42,13 @@ class SiblingFetcher
             if ($contextShelf) {
                 $entities = $contextShelf->visibleBooks()->get();
             } else {
-                $entities = Book::visible()->get();
+                $entities = $this->queries->books->visibleForList()->get();
             }
         }
 
         // Shelf
         if ($entity instanceof Bookshelf) {
-            $entities = Bookshelf::visible()->get();
+            $entities = $this->queries->shelves->visibleForList()->get();
         }
 
         return $entities;
index 8e9f010df0ff6fb5d5ab37e937e0481811d3f3df..39c982cdc92a25219b0df21bfaadac9c4b52a372 100644 (file)
@@ -10,6 +10,7 @@ use BookStack\Entities\Models\Deletion;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\HasCoverImage;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Exceptions\NotifyException;
 use BookStack\Facades\Activity;
 use BookStack\Uploads\AttachmentService;
@@ -20,6 +21,11 @@ use Illuminate\Support\Carbon;
 
 class TrashCan
 {
+    public function __construct(
+        protected EntityQueries $queries,
+    ) {
+    }
+
     /**
      * Send a shelf to the recycle bin.
      *
@@ -203,11 +209,13 @@ class TrashCan
         }
 
         // Remove book template usages
-        Book::query()->where('default_template_id', '=', $page->id)
+        $this->queries->books->start()
+            ->where('default_template_id', '=', $page->id)
             ->update(['default_template_id' => null]);
 
         // Remove chapter template usages
-        Chapter::query()->where('default_template_id', '=', $page->id)
+        $this->queries->chapters->start()
+            ->where('default_template_id', '=', $page->id)
             ->update(['default_template_id' => null]);
 
         $page->forceDelete();
index 8c961fb13061bc7f4169419fd13841c1ad363c79..49eaf0774f1ef8daefe10bb4ef64752b6e84b959 100644 (file)
@@ -8,6 +8,7 @@ use BookStack\Entities\Models\Bookshelf;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Permissions\Models\JointPermission;
 use BookStack\Users\Models\Role;
 use Illuminate\Database\Eloquent\Builder;
@@ -20,6 +21,12 @@ use Illuminate\Support\Facades\DB;
  */
 class JointPermissionBuilder
 {
+    public function __construct(
+        protected EntityQueries $queries,
+    ) {
+    }
+
+
     /**
      * Re-generate all entity permission from scratch.
      */
@@ -36,7 +43,7 @@ class JointPermissionBuilder
         });
 
         // Chunk through all bookshelves
-        Bookshelf::query()->withTrashed()->select(['id', 'owned_by'])
+        $this->queries->shelves->start()->withTrashed()->select(['id', 'owned_by'])
             ->chunk(50, function (EloquentCollection $shelves) use ($roles) {
                 $this->createManyJointPermissions($shelves->all(), $roles);
             });
@@ -88,7 +95,7 @@ class JointPermissionBuilder
         });
 
         // Chunk through all bookshelves
-        Bookshelf::query()->select(['id', 'owned_by'])
+        $this->queries->shelves->start()->select(['id', 'owned_by'])
             ->chunk(100, function ($shelves) use ($roles) {
                 $this->createManyJointPermissions($shelves->all(), $roles);
             });
@@ -99,7 +106,7 @@ class JointPermissionBuilder
      */
     protected function bookFetchQuery(): Builder
     {
-        return Book::query()->withTrashed()
+        return $this->queries->books->start()->withTrashed()
             ->select(['id', 'owned_by'])->with([
                 'chapters' => function ($query) {
                     $query->withTrashed()->select(['id', 'owned_by', 'book_id']);
index f2014ea73f6e50e459d588fc29c09800d3a68d1c..5d2035870bccd79ba4328ec973a18a4140201475 100644 (file)
@@ -2,10 +2,7 @@
 
 namespace BookStack\Permissions;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Entities\Tools\PermissionsUpdater;
 use BookStack\Http\Controller;
 use BookStack\Permissions\Models\EntityPermission;
@@ -14,19 +11,18 @@ use Illuminate\Http\Request;
 
 class PermissionsController extends Controller
 {
-    protected PermissionsUpdater $permissionsUpdater;
-
-    public function __construct(PermissionsUpdater $permissionsUpdater)
-    {
-        $this->permissionsUpdater = $permissionsUpdater;
+    public function __construct(
+        protected PermissionsUpdater $permissionsUpdater,
+        protected EntityQueries $queries,
+    ) {
     }
 
     /**
-     * Show the Permissions view for a page.
+     * Show the permissions view for a page.
      */
     public function showForPage(string $bookSlug, string $pageSlug)
     {
-        $page = Page::getBySlugs($bookSlug, $pageSlug);
+        $page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
         $this->checkOwnablePermission('restrictions-manage', $page);
 
         $this->setPageTitle(trans('entities.pages_permissions'));
@@ -41,7 +37,7 @@ class PermissionsController extends Controller
      */
     public function updateForPage(Request $request, string $bookSlug, string $pageSlug)
     {
-        $page = Page::getBySlugs($bookSlug, $pageSlug);
+        $page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
         $this->checkOwnablePermission('restrictions-manage', $page);
 
         $this->permissionsUpdater->updateFromPermissionsForm($page, $request);
@@ -52,11 +48,11 @@ class PermissionsController extends Controller
     }
 
     /**
-     * Show the Restrictions view for a chapter.
+     * Show the permissions view for a chapter.
      */
     public function showForChapter(string $bookSlug, string $chapterSlug)
     {
-        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
+        $chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
         $this->checkOwnablePermission('restrictions-manage', $chapter);
 
         $this->setPageTitle(trans('entities.chapters_permissions'));
@@ -67,11 +63,11 @@ class PermissionsController extends Controller
     }
 
     /**
-     * Set the restrictions for a chapter.
+     * Set the permissions for a chapter.
      */
     public function updateForChapter(Request $request, string $bookSlug, string $chapterSlug)
     {
-        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
+        $chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
         $this->checkOwnablePermission('restrictions-manage', $chapter);
 
         $this->permissionsUpdater->updateFromPermissionsForm($chapter, $request);
@@ -86,7 +82,7 @@ class PermissionsController extends Controller
      */
     public function showForBook(string $slug)
     {
-        $book = Book::getBySlug($slug);
+        $book = $this->queries->books->findVisibleBySlugOrFail($slug);
         $this->checkOwnablePermission('restrictions-manage', $book);
 
         $this->setPageTitle(trans('entities.books_permissions'));
@@ -97,11 +93,11 @@ class PermissionsController extends Controller
     }
 
     /**
-     * Set the restrictions for a book.
+     * Set the permissions for a book.
      */
     public function updateForBook(Request $request, string $slug)
     {
-        $book = Book::getBySlug($slug);
+        $book = $this->queries->books->findVisibleBySlugOrFail($slug);
         $this->checkOwnablePermission('restrictions-manage', $book);
 
         $this->permissionsUpdater->updateFromPermissionsForm($book, $request);
@@ -116,7 +112,7 @@ class PermissionsController extends Controller
      */
     public function showForShelf(string $slug)
     {
-        $shelf = Bookshelf::getBySlug($slug);
+        $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
         $this->checkOwnablePermission('restrictions-manage', $shelf);
 
         $this->setPageTitle(trans('entities.shelves_permissions'));
@@ -131,7 +127,7 @@ class PermissionsController extends Controller
      */
     public function updateForShelf(Request $request, string $slug)
     {
-        $shelf = Bookshelf::getBySlug($slug);
+        $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
         $this->checkOwnablePermission('restrictions-manage', $shelf);
 
         $this->permissionsUpdater->updateFromPermissionsForm($shelf, $request);
@@ -146,7 +142,7 @@ class PermissionsController extends Controller
      */
     public function copyShelfPermissionsToBooks(string $slug)
     {
-        $shelf = Bookshelf::getBySlug($slug);
+        $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
         $this->checkOwnablePermission('restrictions-manage', $shelf);
 
         $updateCount = $this->permissionsUpdater->updateBookPermissionsFromShelf($shelf);
index b9c3ad205aea12a2f2d38e4199d5506b64b04222..1fd4c1b3e3c2401830c904fd2efd946797ea85b1 100644 (file)
@@ -3,6 +3,7 @@
 namespace BookStack\References;
 
 use BookStack\App\Model;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\References\ModelResolvers\BookLinkModelResolver;
 use BookStack\References\ModelResolvers\BookshelfLinkModelResolver;
 use BookStack\References\ModelResolvers\ChapterLinkModelResolver;
@@ -85,12 +86,14 @@ class CrossLinkParser
      */
     public static function createWithEntityResolvers(): self
     {
+        $queries = app()->make(EntityQueries::class);
+
         return new self([
-            new PagePermalinkModelResolver(),
-            new PageLinkModelResolver(),
-            new ChapterLinkModelResolver(),
-            new BookLinkModelResolver(),
-            new BookshelfLinkModelResolver(),
+            new PagePermalinkModelResolver($queries->pages),
+            new PageLinkModelResolver($queries->pages),
+            new ChapterLinkModelResolver($queries->chapters),
+            new BookLinkModelResolver($queries->books),
+            new BookshelfLinkModelResolver($queries->shelves),
         ]);
     }
 }
index d404fe2fd84dd9d2596687d70e3f8fa0fe18be43..a671fbf570062e836aee77185473804a58b7507d 100644 (file)
@@ -4,9 +4,15 @@ namespace BookStack\References\ModelResolvers;
 
 use BookStack\App\Model;
 use BookStack\Entities\Models\Book;
+use BookStack\Entities\Queries\BookQueries;
 
 class BookLinkModelResolver implements CrossLinkModelResolver
 {
+    public function __construct(
+        protected BookQueries $queries
+    ) {
+    }
+
     public function resolve(string $link): ?Model
     {
         $pattern = '/^' . preg_quote(url('/books'), '/') . '\/([\w-]+)' . '([#?\/]|$)/';
@@ -19,7 +25,7 @@ class BookLinkModelResolver implements CrossLinkModelResolver
         $bookSlug = $matches[1];
 
         /** @var ?Book $model */
-        $model = Book::query()->where('slug', '=', $bookSlug)->first(['id']);
+        $model = $this->queries->start()->where('slug', '=', $bookSlug)->first(['id']);
 
         return $model;
     }
index cc9df034e6055e001bfffaa01e8db9ace4285f68..d79c760e070b38c9c790706088a8d55cefecab15 100644 (file)
@@ -4,9 +4,14 @@ namespace BookStack\References\ModelResolvers;
 
 use BookStack\App\Model;
 use BookStack\Entities\Models\Bookshelf;
+use BookStack\Entities\Queries\BookshelfQueries;
 
 class BookshelfLinkModelResolver implements CrossLinkModelResolver
 {
+    public function __construct(
+        protected BookshelfQueries $queries
+    ) {
+    }
     public function resolve(string $link): ?Model
     {
         $pattern = '/^' . preg_quote(url('/shelves'), '/') . '\/([\w-]+)' . '([#?\/]|$)/';
@@ -19,7 +24,7 @@ class BookshelfLinkModelResolver implements CrossLinkModelResolver
         $shelfSlug = $matches[1];
 
         /** @var ?Bookshelf $model */
-        $model = Bookshelf::query()->where('slug', '=', $shelfSlug)->first(['id']);
+        $model = $this->queries->start()->where('slug', '=', $shelfSlug)->first(['id']);
 
         return $model;
     }
index 4733c68eead62c34529683143a4ac88638566038..318b5ed35f41c014a85dae3bd49a9ed528db65a7 100644 (file)
@@ -4,9 +4,15 @@ namespace BookStack\References\ModelResolvers;
 
 use BookStack\App\Model;
 use BookStack\Entities\Models\Chapter;
+use BookStack\Entities\Queries\ChapterQueries;
 
 class ChapterLinkModelResolver implements CrossLinkModelResolver
 {
+    public function __construct(
+        protected ChapterQueries $queries
+    ) {
+    }
+
     public function resolve(string $link): ?Model
     {
         $pattern = '/^' . preg_quote(url('/books'), '/') . '\/([\w-]+)' . '\/chapter\/' . '([\w-]+)' . '([#?\/]|$)/';
@@ -20,7 +26,7 @@ class ChapterLinkModelResolver implements CrossLinkModelResolver
         $chapterSlug = $matches[2];
 
         /** @var ?Chapter $model */
-        $model = Chapter::query()->whereSlugs($bookSlug, $chapterSlug)->first(['id']);
+        $model = $this->queries->usingSlugs($bookSlug, $chapterSlug)->first(['id']);
 
         return $model;
     }
index 736382becdd1cc38b849b973512f9a81c3b54fec..9a01416a4453fb1417b5c9ec6c2b52339ba9630a 100644 (file)
@@ -4,9 +4,15 @@ namespace BookStack\References\ModelResolvers;
 
 use BookStack\App\Model;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\PageQueries;
 
 class PageLinkModelResolver implements CrossLinkModelResolver
 {
+    public function __construct(
+        protected PageQueries $queries
+    ) {
+    }
+
     public function resolve(string $link): ?Model
     {
         $pattern = '/^' . preg_quote(url('/books'), '/') . '\/([\w-]+)' . '\/page\/' . '([\w-]+)' . '([#?\/]|$)/';
@@ -20,7 +26,7 @@ class PageLinkModelResolver implements CrossLinkModelResolver
         $pageSlug = $matches[2];
 
         /** @var ?Page $model */
-        $model = Page::query()->whereSlugs($bookSlug, $pageSlug)->first(['id']);
+        $model = $this->queries->usingSlugs($bookSlug, $pageSlug)->first(['id']);
 
         return $model;
     }
index 9ed00b36dd4c3326ed928163e2007049ac7151ea..59d509f3399b972ff576cca417e160171f96bd0b 100644 (file)
@@ -4,9 +4,15 @@ namespace BookStack\References\ModelResolvers;
 
 use BookStack\App\Model;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\PageQueries;
 
 class PagePermalinkModelResolver implements CrossLinkModelResolver
 {
+    public function __construct(
+        protected PageQueries $queries
+    ) {
+    }
+
     public function resolve(string $link): ?Model
     {
         $pattern = '/^' . preg_quote(url('/link'), '/') . '\/(\d+)/';
@@ -18,7 +24,7 @@ class PagePermalinkModelResolver implements CrossLinkModelResolver
 
         $id = intval($matches[1]);
         /** @var ?Page $model */
-        $model = Page::query()->find($id, ['id']);
+        $model = $this->queries->start()->find($id, ['id']);
 
         return $model;
     }
index 991f47225b8e044094ba31e3ebf4b3fdd09cd036..57dbcce3c5129763a5a9d43a6966f293cc2c8585 100644 (file)
@@ -6,12 +6,14 @@ use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Bookshelf;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Http\Controller;
 
 class ReferenceController extends Controller
 {
     public function __construct(
-        protected ReferenceFetcher $referenceFetcher
+        protected ReferenceFetcher $referenceFetcher,
+        protected EntityQueries $queries,
     ) {
     }
 
@@ -20,7 +22,7 @@ class ReferenceController extends Controller
      */
     public function page(string $bookSlug, string $pageSlug)
     {
-        $page = Page::getBySlugs($bookSlug, $pageSlug);
+        $page = $this->queries->pages->findVisibleBySlugsOrFail($bookSlug, $pageSlug);
         $references = $this->referenceFetcher->getReferencesToEntity($page);
 
         return view('pages.references', [
@@ -34,7 +36,7 @@ class ReferenceController extends Controller
      */
     public function chapter(string $bookSlug, string $chapterSlug)
     {
-        $chapter = Chapter::getBySlugs($bookSlug, $chapterSlug);
+        $chapter = $this->queries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
         $references = $this->referenceFetcher->getReferencesToEntity($chapter);
 
         return view('chapters.references', [
@@ -48,7 +50,7 @@ class ReferenceController extends Controller
      */
     public function book(string $slug)
     {
-        $book = Book::getBySlug($slug);
+        $book = $this->queries->books->findVisibleBySlugOrFail($slug);
         $references = $this->referenceFetcher->getReferencesToEntity($book);
 
         return view('books.references', [
@@ -62,7 +64,7 @@ class ReferenceController extends Controller
      */
     public function shelf(string $slug)
     {
-        $shelf = Bookshelf::getBySlug($slug);
+        $shelf = $this->queries->shelves->findVisibleBySlugOrFail($slug);
         $references = $this->referenceFetcher->getReferencesToEntity($shelf);
 
         return view('shelves.references', [
index 6cf12a57920631ecebdff6fdddf01938d80f1ac6..bc3f2ddb403e49bfd8b47e950c872fb4f6036598 100644 (file)
@@ -130,12 +130,12 @@ class SearchController extends Controller
     /**
      * Search siblings items in the system.
      */
-    public function searchSiblings(Request $request)
+    public function searchSiblings(Request $request, SiblingFetcher $siblingFetcher)
     {
         $type = $request->get('entity_type', null);
         $id = $request->get('entity_id', null);
 
-        $entities = (new SiblingFetcher())->fetch($type, $id);
+        $entities = $siblingFetcher->fetch($type, $id);
 
         return view('entities.list-basic', ['entities' => $entities, 'style' => 'compact']);
     }
index 62eeecf39a9ca961ec53c4b18d854190de5ea601..0382ae08a6d18c41b530fbf7c0a9f7cd12eb367b 100644 (file)
@@ -14,7 +14,7 @@ class MaintenanceController extends Controller
     /**
      * Show the page for application maintenance.
      */
-    public function index()
+    public function index(TrashCan $trashCan)
     {
         $this->checkPermission('settings-manage');
         $this->setPageTitle(trans('settings.maint'));
@@ -23,7 +23,7 @@ class MaintenanceController extends Controller
         $version = trim(file_get_contents(base_path('version')));
 
         // Recycle bin details
-        $recycleStats = (new TrashCan())->getTrashedCounts();
+        $recycleStats = $trashCan->getTrashedCounts();
 
         return view('settings.maintenance', [
             'version'      => $version,
index 1655a4cc3aa0d9c74a12f355a8cbb6880f011711..ee2cb8a3533988cb3e352158bfcfc519d69a8ad1 100644 (file)
@@ -5,6 +5,7 @@ namespace BookStack\Uploads;
 use BookStack\Entities\Models\Book;
 use BookStack\Entities\Models\Bookshelf;
 use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Exceptions\ImageUploadException;
 use Exception;
 use Illuminate\Support\Facades\DB;
@@ -20,6 +21,7 @@ class ImageService
     public function __construct(
         protected ImageStorage $storage,
         protected ImageResizer $resizer,
+        protected EntityQueries $queries,
     ) {
     }
 
@@ -278,15 +280,15 @@ class ImageService
         }
 
         if ($imageType === 'gallery' || $imageType === 'drawio') {
-            return Page::visible()->where('id', '=', $image->uploaded_to)->exists();
+            return $this->queries->pages->visibleForList()->where('id', '=', $image->uploaded_to)->exists();
         }
 
         if ($imageType === 'cover_book') {
-            return Book::visible()->where('id', '=', $image->uploaded_to)->exists();
+            return $this->queries->books->visibleForList()->where('id', '=', $image->uploaded_to)->exists();
         }
 
         if ($imageType === 'cover_bookshelf') {
-            return Bookshelf::visible()->where('id', '=', $image->uploaded_to)->exists();
+            return $this->queries->shelves->visibleForList()->where('id', '=', $image->uploaded_to)->exists();
         }
 
         return false;
index bdf268260a1a7db0121ce0935c8cd03dd0684c69..963d69a624700efd2df0cf1cbd8e90e5fabc0f11 100644 (file)
@@ -10,16 +10,25 @@ use BookStack\Users\UserRepo;
 
 class UserProfileController extends Controller
 {
+    public function __construct(
+        protected UserRepo $userRepo,
+        protected ActivityQueries $activityQueries,
+        protected UserContentCounts $contentCounts,
+        protected UserRecentlyCreatedContent $recentlyCreatedContent
+    ) {
+    }
+
+
     /**
      * Show the user profile page.
      */
-    public function show(UserRepo $repo, ActivityQueries $activities, string $slug)
+    public function show(string $slug)
     {
-        $user = $repo->getBySlug($slug);
+        $user = $this->userRepo->getBySlug($slug);
 
-        $userActivity = $activities->userActivity($user);
-        $recentlyCreated = (new UserRecentlyCreatedContent())->run($user, 5);
-        $assetCounts = (new UserContentCounts())->run($user);
+        $userActivity = $this->activityQueries->userActivity($user);
+        $recentlyCreated = $this->recentlyCreatedContent->run($user, 5);
+        $assetCounts = $this->contentCounts->run($user);
 
         $this->setPageTitle($user->name);
 
index 178d8536b1d44441d4dc0ef0950e44947b712992..af38bfa7e2a2df6c880de67da030870535a9b26e 100644 (file)
@@ -2,10 +2,7 @@
 
 namespace BookStack\Users\Queries;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Users\Models\User;
 
 /**
@@ -13,6 +10,12 @@ use BookStack\Users\Models\User;
  */
 class UserContentCounts
 {
+    public function __construct(
+        protected EntityQueries $queries,
+    ) {
+    }
+
+
     /**
      * @return array{pages: int, chapters: int, books: int, shelves: int}
      */
@@ -21,10 +24,10 @@ class UserContentCounts
         $createdBy = ['created_by' => $user->id];
 
         return [
-            'pages'    => Page::visible()->where($createdBy)->count(),
-            'chapters' => Chapter::visible()->where($createdBy)->count(),
-            'books'    => Book::visible()->where($createdBy)->count(),
-            'shelves'  => Bookshelf::visible()->where($createdBy)->count(),
+            'pages'    => $this->queries->pages->visibleForList()->where($createdBy)->count(),
+            'chapters' => $this->queries->chapters->visibleForList()->where($createdBy)->count(),
+            'books'    => $this->queries->books->visibleForList()->where($createdBy)->count(),
+            'shelves'  => $this->queries->shelves->visibleForList()->where($createdBy)->count(),
         ];
     }
 }
index 23db2c1f1a2a42ad38254b0237496f904a1537ec..23850e072010de48d164544fac92d0eeebb780c5 100644 (file)
@@ -2,10 +2,7 @@
 
 namespace BookStack\Users\Queries;
 
-use BookStack\Entities\Models\Book;
-use BookStack\Entities\Models\Bookshelf;
-use BookStack\Entities\Models\Chapter;
-use BookStack\Entities\Models\Page;
+use BookStack\Entities\Queries\EntityQueries;
 use BookStack\Users\Models\User;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
@@ -15,6 +12,11 @@ use Illuminate\Database\Eloquent\Collection;
  */
 class UserRecentlyCreatedContent
 {
+    public function __construct(
+        protected EntityQueries $queries,
+    ) {
+    }
+
     /**
      * @return array{pages: Collection, chapters: Collection, books: Collection, shelves: Collection}
      */
@@ -28,10 +30,10 @@ class UserRecentlyCreatedContent
         };
 
         return [
-            'pages'    => $query(Page::visible()->where('draft', '=', false)),
-            'chapters' => $query(Chapter::visible()),
-            'books'    => $query(Book::visible()),
-            'shelves'  => $query(Bookshelf::visible()),
+            'pages'    => $query($this->queries->pages->visibleForList()->where('draft', '=', false)),
+            'chapters' => $query($this->queries->chapters->visibleForList()),
+            'books'    => $query($this->queries->books->visibleForList()),
+            'shelves'  => $query($this->queries->shelves->visibleForList()),
         ];
     }
 }
index 3740892460b296e44b7d4c88e17afb6c7709d421..04dff293facd20805e1281b4264f8808470c902e 100644 (file)
@@ -317,7 +317,7 @@ class BookTest extends TestCase
         $copy = Book::query()->where('name', '=', 'My copy book')->first();
 
         $resp->assertRedirect($copy->getUrl());
-        $this->assertEquals($book->getDirectChildren()->count(), $copy->getDirectChildren()->count());
+        $this->assertEquals($book->getDirectVisibleChildren()->count(), $copy->getDirectVisibleChildren()->count());
 
         $this->get($copy->getUrl())->assertSee($book->description_html, false);
     }
@@ -329,7 +329,7 @@ class BookTest extends TestCase
 
         // Hide child content
         /** @var BookChild $page */
-        foreach ($book->getDirectChildren() as $child) {
+        foreach ($book->getDirectVisibleChildren() as $child) {
             $this->permissions->setEntityPermissions($child, [], []);
         }
 
@@ -337,7 +337,7 @@ class BookTest extends TestCase
         /** @var Book $copy */
         $copy = Book::query()->where('name', '=', 'My copy book')->first();
 
-        $this->assertEquals(0, $copy->getDirectChildren()->count());
+        $this->assertEquals(0, $copy->getDirectVisibleChildren()->count());
     }
 
     public function test_copy_does_not_copy_pages_or_chapters_if_user_cant_create()
index 9b77a32ab80e9e63f180a80243230733b36b02df..dcc0620444628c92680666578db25e46831e28b6 100644 (file)
@@ -303,7 +303,7 @@ class EntitySearchTest extends TestCase
     public function test_sibling_search_for_pages_without_chapter()
     {
         $page = $this->entities->pageNotWithinChapter();
-        $bookChildren = $page->book->getDirectChildren();
+        $bookChildren = $page->book->getDirectVisibleChildren();
         $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 
         $search = $this->actingAs($this->users->viewer())->get("/search/entity/siblings?entity_id={$page->id}&entity_type=page");
@@ -318,7 +318,7 @@ class EntitySearchTest extends TestCase
     public function test_sibling_search_for_chapters()
     {
         $chapter = $this->entities->chapter();
-        $bookChildren = $chapter->book->getDirectChildren();
+        $bookChildren = $chapter->book->getDirectVisibleChildren();
         $this->assertGreaterThan(2, count($bookChildren), 'Ensure we\'re testing with at least 1 sibling');
 
         $search = $this->actingAs($this->users->viewer())->get("/search/entity/siblings?entity_id={$chapter->id}&entity_type=chapter");