]> BookStack Code Mirror - bookstack/blob - app/Entities/Models/Book.php
API: Added comment-read endpoint, added api docs section descriptions
[bookstack] / app / Entities / Models / Book.php
1 <?php
2
3 namespace BookStack\Entities\Models;
4
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;
14
15 /**
16  * Class Book.
17  *
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
28  */
29 class Book extends Entity implements HasDescriptionInterface, HasCoverInterface, HasDefaultTemplateInterface
30 {
31     use HasFactory;
32     use ContainerTrait;
33
34     public float $searchFactor = 1.2;
35
36     protected $hidden = ['pivot', 'deleted_at', 'description_html', 'entity_id', 'entity_type', 'chapter_id', 'book_id', 'priority'];
37     protected $fillable = ['name'];
38
39     /**
40      * Get the url for this book.
41      */
42     public function getUrl(string $path = ''): string
43     {
44         return url('/books/' . implode('/', [urlencode($this->slug), trim($path, '/')]));
45     }
46
47     /**
48      * Get all pages within this book.
49      * @return HasMany<Page, $this>
50      */
51     public function pages(): HasMany
52     {
53         return $this->hasMany(Page::class);
54     }
55
56     /**
57      * Get the direct child pages of this book.
58      */
59     public function directPages(): HasMany
60     {
61         return $this->pages()->whereNull('chapter_id');
62     }
63
64     /**
65      * Get all chapters within this book.
66      * @return HasMany<Chapter, $this>
67      */
68     public function chapters(): HasMany
69     {
70         return $this->hasMany(Chapter::class)
71             ->where('type', '=', 'chapter');
72     }
73
74     /**
75      * Get the shelves this book is contained within.
76      */
77     public function shelves(): BelongsToMany
78     {
79         return $this->belongsToMany(Bookshelf::class, 'bookshelves_books', 'book_id', 'bookshelf_id');
80     }
81
82     /**
83      * Get the direct child items within this book.
84      */
85     public function getDirectVisibleChildren(): Collection
86     {
87         $pages = $this->directPages()->scopes('visible')->get();
88         $chapters = $this->chapters()->scopes('visible')->get();
89
90         return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
91     }
92
93     public function defaultTemplate(): EntityDefaultTemplate
94     {
95         return new EntityDefaultTemplate($this);
96     }
97
98     public function cover(): BelongsTo
99     {
100         return $this->belongsTo(Image::class, 'image_id');
101     }
102
103     public function coverInfo(): EntityCover
104     {
105         return new EntityCover($this);
106     }
107
108     /**
109      * Get the sort rule assigned to this container, if existing.
110      */
111     public function sortRule(): BelongsTo
112     {
113         return $this->belongsTo(SortRule::class);
114     }
115 }