mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-02-11 07:38:57 +00:00
108 lines
3.2 KiB
PHP
108 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace BookStack\Entities\Tools;
|
|
|
|
use BookStack\Entities\Models\Book;
|
|
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 BookStack\Sorting\BookSortMap;
|
|
use BookStack\Sorting\BookSortMapItem;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class BookContents
|
|
{
|
|
protected EntityQueries $queries;
|
|
|
|
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.
|
|
*/
|
|
public function getLastPriority(): int
|
|
{
|
|
$maxPage = $this->book->pages()
|
|
->where('draft', '=', false)
|
|
->where('chapter_id', '=', 0)
|
|
->max('priority');
|
|
|
|
$maxChapter = $this->book->chapters()
|
|
->max('priority');
|
|
|
|
return max($maxChapter, $maxPage, 1);
|
|
}
|
|
|
|
/**
|
|
* Get the contents as a sorted collection tree.
|
|
*/
|
|
public function getTree(bool $showDrafts = false, bool $renderPages = false): Collection
|
|
{
|
|
$pages = $this->getPages($showDrafts, $renderPages);
|
|
$chapters = $this->book->chapters()->scopes('visible')->get();
|
|
$all = collect()->concat($pages)->concat($chapters);
|
|
$chapterMap = $chapters->keyBy('id');
|
|
$lonePages = collect();
|
|
|
|
$pages->groupBy('chapter_id')->each(function ($pages, $chapter_id) use ($chapterMap, &$lonePages) {
|
|
$chapter = $chapterMap->get($chapter_id);
|
|
if ($chapter) {
|
|
$chapter->setAttribute('visible_pages', collect($pages)->sortBy($this->bookChildSortFunc()));
|
|
} else {
|
|
$lonePages = $lonePages->concat($pages);
|
|
}
|
|
});
|
|
|
|
$chapters->whereNull('visible_pages')->each(function (Chapter $chapter) {
|
|
$chapter->setAttribute('visible_pages', collect([]));
|
|
});
|
|
|
|
$all->each(function (Entity $entity) use ($renderPages) {
|
|
$entity->setRelation('book', $this->book);
|
|
|
|
if ($renderPages && $entity instanceof Page) {
|
|
$entity->html = (new PageContent($entity))->render();
|
|
}
|
|
});
|
|
|
|
return collect($chapters)->concat($lonePages)->sortBy($this->bookChildSortFunc());
|
|
}
|
|
|
|
/**
|
|
* Function for providing a sorting score for an entity in relation to the
|
|
* other items within the book.
|
|
*/
|
|
protected function bookChildSortFunc(): callable
|
|
{
|
|
return function (Entity $entity) {
|
|
if (isset($entity['draft']) && $entity['draft']) {
|
|
return -100;
|
|
}
|
|
|
|
return $entity['priority'] ?? 0;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get the visible pages within this book.
|
|
*/
|
|
protected function getPages(bool $showDrafts = false, bool $getPageContent = false): Collection
|
|
{
|
|
if ($getPageContent) {
|
|
$query = $this->queries->pages->visibleWithContents();
|
|
} else {
|
|
$query = $this->queries->pages->visibleForList();
|
|
}
|
|
|
|
if (!$showDrafts) {
|
|
$query->where('draft', '=', false);
|
|
}
|
|
|
|
return $query->where('book_id', '=', $this->book->id)->get();
|
|
}
|
|
}
|