3 namespace BookStack\Entities\Models;
5 use BookStack\Entities\Tools\EntityCover;
6 use BookStack\Entities\Tools\EntityDefaultTemplate;
7 use BookStack\Sorting\SortRule;
8 use BookStack\Uploads\Image;
9 use Illuminate\Database\Eloquent\Factories\HasFactory;
10 use Illuminate\Database\Eloquent\Relations\BelongsTo;
11 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
12 use Illuminate\Database\Eloquent\Relations\HasMany;
13 use Illuminate\Support\Collection;
18 * @property string $description
19 * @property string $description_html
20 * @property int $image_id
21 * @property ?int $default_template_id
22 * @property ?int $sort_rule_id
23 * @property \Illuminate\Database\Eloquent\Collection $chapters
24 * @property \Illuminate\Database\Eloquent\Collection $pages
25 * @property \Illuminate\Database\Eloquent\Collection $directPages
26 * @property \Illuminate\Database\Eloquent\Collection $shelves
27 * @property ?SortRule $sortRule
29 class Book extends Entity implements HasDescriptionInterface, HasCoverInterface, HasDefaultTemplateInterface
34 public float $searchFactor = 1.2;
36 protected $hidden = ['pivot', 'deleted_at', 'description_html', 'entity_id', 'entity_type', 'chapter_id', 'book_id', 'priority'];
37 protected $fillable = ['name'];
40 * Get the url for this book.
42 public function getUrl(string $path = ''): string
44 return url('/books/' . implode('/', [urlencode($this->slug), trim($path, '/')]));
48 * Get all pages within this book.
49 * @return HasMany<Page, $this>
51 public function pages(): HasMany
53 return $this->hasMany(Page::class);
57 * Get the direct child pages of this book.
59 public function directPages(): HasMany
61 return $this->pages()->whereNull('chapter_id');
65 * Get all chapters within this book.
66 * @return HasMany<Chapter, $this>
68 public function chapters(): HasMany
70 return $this->hasMany(Chapter::class)
71 ->where('type', '=', 'chapter');
75 * Get the shelves this book is contained within.
77 public function shelves(): BelongsToMany
79 return $this->belongsToMany(Bookshelf::class, 'bookshelves_books', 'book_id', 'bookshelf_id');
83 * Get the direct child items within this book.
85 public function getDirectVisibleChildren(): Collection
87 $pages = $this->directPages()->scopes('visible')->get();
88 $chapters = $this->chapters()->scopes('visible')->get();
90 return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
93 public function defaultTemplate(): EntityDefaultTemplate
95 return new EntityDefaultTemplate($this);
98 public function cover(): BelongsTo
100 return $this->belongsTo(Image::class, 'image_id');
103 public function coverInfo(): EntityCover
105 return new EntityCover($this);
109 * Get the sort rule assigned to this container, if existing.
111 public function sortRule(): BelongsTo
113 return $this->belongsTo(SortRule::class);