]> BookStack Code Mirror - bookstack/blobdiff - app/Entities/Tools/BookContents.php
Tests: Updated comment test to account for new editor usage
[bookstack] / app / Entities / Tools / BookContents.php
index 96142bb7f4698ad130ae6e0f587d13e390a34dcd..7dd3f3e11adade81eea09005082948c1d3c42439 100644 (file)
@@ -7,34 +7,32 @@ use BookStack\Entities\Models\BookChild;
 use BookStack\Entities\Models\Chapter;
 use BookStack\Entities\Models\Entity;
 use BookStack\Entities\Models\Page;
-use BookStack\Exceptions\SortOperationException;
+use BookStack\Entities\Queries\EntityQueries;
+use BookStack\Sorting\BookSortMap;
+use BookStack\Sorting\BookSortMapItem;
 use Illuminate\Support\Collection;
 
 class BookContents
 {
-    /**
-     * @var Book
-     */
-    protected $book;
+    protected EntityQueries $queries;
 
-    /**
-     * BookContents constructor.
-     */
-    public function __construct(Book $book)
-    {
-        $this->book = $book;
+    public function __construct(
+        protected Book $book,
+    ) {
+        $this->queries = app()->make(EntityQueries::class);
     }
 
     /**
-     * Get the current priority of the last item
-     * at the top-level of the book.
+     * Get the current priority of the last item at the top-level of the book.
      */
     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);
@@ -46,7 +44,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();
@@ -95,124 +93,16 @@ 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();
-    }
-
-    /**
-     * Sort the books content using the given sort map.
-     * Returns a list of books that were involved in the operation.
-     *
-     * @throws SortOperationException
-     */
-    public function sortUsingMap(BookSortMap $sortMap): Collection
-    {
-        // Load models into map
-        $this->loadModelsIntoSortMap($sortMap);
-        $booksInvolved = $this->getBooksInvolvedInSort($sortMap);
-
-        // Perform the sort
-        foreach ($sortMap->all() as $item) {
-            $this->applySortUpdates($item);
-        }
-
-        // Update permissions and activity.
-        $booksInvolved->each(function (Book $book) {
-            $book->rebuildPermissions();
-        });
-
-        return $booksInvolved;
-    }
-
-    /**
-     * Using the given sort map item, detect changes for the related model
-     * and update it if required.
-     */
-    protected function applySortUpdates(BookSortMapItem $sortMapItem): void
-    {
-        $model = $sortMapItem->model;
-        if (!$model) {
-            return;
-        }
-
-        $priorityChanged = $model->priority !== $sortMapItem->sort;
-        $bookChanged = $model->book_id !== $sortMapItem->parentBookId;
-        $chapterChanged = ($model instanceof Page) && $model->chapter_id !== $sortMapItem->parentChapterId;
-
-        if ($bookChanged) {
-            $model->changeBook($sortMapItem->parentBookId);
-        }
-
-        if ($chapterChanged) {
-            $model->chapter_id = intval($sortMapItem->parentChapterId);
-            $model->save();
-        }
-
-        if ($priorityChanged) {
-            $model->priority = $sortMapItem->sort;
-            $model->save();
-        }
-    }
-
-    /**
-     * Load models from the database into the given sort map.
-     */
-    protected function loadModelsIntoSortMap(BookSortMap $sortMap): void
-    {
-        $collection = collect($sortMap->all());
-
-        $keyMap = $collection->keyBy(function (BookSortMapItem $sortMapItem) {
-            return  $sortMapItem->type . ':' . $sortMapItem->id;
-        });
-
-        $pageIds = $collection->where('type', '=', 'page')->pluck('id');
-        $chapterIds = $collection->where('type', '=', 'chapter')->pluck('id');
-
-        $pages = Page::visible()->whereIn('id', $pageIds)->get();
-        $chapters = Chapter::visible()->whereIn('id', $chapterIds)->get();
-
-        foreach ($pages as $page) {
-            /** @var BookSortMapItem $sortItem */
-            $sortItem = $keyMap->get('page:' . $page->id);
-            $sortItem->model = $page;
-        }
-
-        foreach ($chapters as $chapter) {
-            /** @var BookSortMapItem $sortItem */
-            $sortItem = $keyMap->get('chapter:' . $chapter->id);
-            $sortItem->model = $chapter;
-        }
-    }
-
-    /**
-     * Get the books involved in a sort.
-     * The given sort map should have its models loaded first.
-     *
-     * @throws SortOperationException
-     */
-    protected function getBooksInvolvedInSort(BookSortMap $sortMap): Collection
-    {
-        $collection = collect($sortMap->all());
-
-        $bookIdsInvolved = array_unique(array_merge(
-            [$this->book->id],
-            $collection->pluck('parentBookId')->values()->all(),
-            $collection->pluck('model.book_id')->values()->all(),
-        ));
-        
-        $books = Book::hasPermission('update')->whereIn('id', $bookIdsInvolved)->get();
-
-        if (count($books) !== count($bookIdsInvolved)) {
-            throw new SortOperationException('Could not find all books requested in sort operation');
-        }
-
-        return $books;
+        return $query->where('book_id', '=', $this->book->id)->get();
     }
 }