]> BookStack Code Mirror - bookstack/blobdiff - app/Entities/Tools/BookContents.php
respective book and chapter structure added.
[bookstack] / app / Entities / Tools / BookContents.php
index 99602de414034a44ca9db88a4cd47655d814254f..7fa2134b7fad60627393c334781d512542133298 100644 (file)
@@ -7,33 +7,30 @@ 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
 {
-    /**
-     * @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);
@@ -45,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();
@@ -94,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();
     }
 
     /**
@@ -119,9 +118,10 @@ class BookContents
         // Sort our changes from our map to be chapters first
         // Since they need to be process to ensure book alignment for child page changes.
         $sortMapItems = $sortMap->all();
-        usort($sortMapItems, function(BookSortMapItem $itemA, BookSortMapItem $itemB) {
+        usort($sortMapItems, function (BookSortMapItem $itemA, BookSortMapItem $itemB) {
             $aScore = $itemA->type === 'page' ? 2 : 1;
             $bScore = $itemB->type === 'page' ? 2 : 1;
+
             return $aScore - $bScore;
         });
 
@@ -132,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
@@ -167,9 +167,9 @@ class BookContents
             return;
         }
 
-        $currentParentKey =  'book:' . $model->book_id;
+        $currentParentKey = 'book:' . $model->book_id;
         if ($model instanceof Page && $model->chapter_id) {
-             $currentParentKey = 'chapter:' . $model->chapter_id;
+            $currentParentKey = 'chapter:' . $model->chapter_id;
         }
 
         $currentParent = $modelMap[$currentParentKey] ?? null;
@@ -187,7 +187,7 @@ class BookContents
             $model->changeBook($newBook->id);
         }
 
-        if ($chapterChanged) {
+        if ($model instanceof Page && $chapterChanged) {
             $model->chapter_id = $newChapter->id ?? 0;
         }
 
@@ -241,7 +241,7 @@ class BookContents
             }
 
             $hasPageEditPermission = userCan('page-update', $model);
-            $newParentInRightLocation = ($newParent instanceof Book || $newParent->book_id === $newBook->id);
+            $newParentInRightLocation = ($newParent instanceof Book || ($newParent instanceof Chapter && $newParent->book_id === $newBook->id));
             $newParentPermission = ($newParent instanceof Chapter) ? 'chapter-update' : 'book-update';
             $hasNewParentPermission = userCan($newParentPermission, $newParent);
 
@@ -265,6 +265,7 @@ class BookContents
 
     /**
      * Load models from the database into the given sort map.
+     *
      * @return array<string, Entity>
      */
     protected function loadModelsFromSortMap(BookSortMap $sortMap): array
@@ -272,8 +273,8 @@ class BookContents
         $modelMap = [];
         $ids = [
             'chapter' => [],
-            'page' => [],
-            'book' => [],
+            'page'    => [],
+            'book'    => [],
         ];
 
         foreach ($sortMap->all() as $sortMapItem) {
@@ -284,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;
@@ -294,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;