]> BookStack Code Mirror - bookstack/blob - app/Entities/Models/Book.php
Sorting: Renamed sort set to sort rule
[bookstack] / app / Entities / Models / Book.php
1 <?php
2
3 namespace BookStack\Entities\Models;
4
5 use BookStack\Sorting\SortRule;
6 use BookStack\Uploads\Image;
7 use Exception;
8 use Illuminate\Database\Eloquent\Factories\HasFactory;
9 use Illuminate\Database\Eloquent\Relations\BelongsTo;
10 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11 use Illuminate\Database\Eloquent\Relations\HasMany;
12 use Illuminate\Support\Collection;
13
14 /**
15  * Class Book.
16  *
17  * @property string                                   $description
18  * @property int                                      $image_id
19  * @property ?int                                     $default_template_id
20  * @property ?int                                     $sort_rule_id
21  * @property Image|null                               $cover
22  * @property \Illuminate\Database\Eloquent\Collection $chapters
23  * @property \Illuminate\Database\Eloquent\Collection $pages
24  * @property \Illuminate\Database\Eloquent\Collection $directPages
25  * @property \Illuminate\Database\Eloquent\Collection $shelves
26  * @property ?Page                                    $defaultTemplate
27  * @property ?SortRule                                 $sortRule
28  */
29 class Book extends Entity implements HasCoverImage
30 {
31     use HasFactory;
32     use HasHtmlDescription;
33
34     public float $searchFactor = 1.2;
35
36     protected $fillable = ['name'];
37     protected $hidden = ['pivot', 'image_id', 'deleted_at', 'description_html'];
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      * Returns book cover image, if book cover not exists return default cover image.
49      */
50     public function getBookCover(int $width = 440, int $height = 250): string
51     {
52         $default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
53         if (!$this->image_id || !$this->cover) {
54             return $default;
55         }
56
57         try {
58             return $this->cover->getThumb($width, $height, false) ?? $default;
59         } catch (Exception $err) {
60             return $default;
61         }
62     }
63
64     /**
65      * Get the cover image of the book.
66      */
67     public function cover(): BelongsTo
68     {
69         return $this->belongsTo(Image::class, 'image_id');
70     }
71
72     /**
73      * Get the type of the image model that is used when storing a cover image.
74      */
75     public function coverImageTypeKey(): string
76     {
77         return 'cover_book';
78     }
79
80     /**
81      * Get the Page that is used as default template for newly created pages within this Book.
82      */
83     public function defaultTemplate(): BelongsTo
84     {
85         return $this->belongsTo(Page::class, 'default_template_id');
86     }
87
88     /**
89      * Get the sort set assigned to this book, if existing.
90      */
91     public function sortRule(): BelongsTo
92     {
93         return $this->belongsTo(SortRule::class);
94     }
95
96     /**
97      * Get all pages within this book.
98      */
99     public function pages(): HasMany
100     {
101         return $this->hasMany(Page::class);
102     }
103
104     /**
105      * Get the direct child pages of this book.
106      */
107     public function directPages(): HasMany
108     {
109         return $this->pages()->where('chapter_id', '=', '0');
110     }
111
112     /**
113      * Get all chapters within this book.
114      */
115     public function chapters(): HasMany
116     {
117         return $this->hasMany(Chapter::class);
118     }
119
120     /**
121      * Get the shelves this book is contained within.
122      */
123     public function shelves(): BelongsToMany
124     {
125         return $this->belongsToMany(Bookshelf::class, 'bookshelves_books', 'book_id', 'bookshelf_id');
126     }
127
128     /**
129      * Get the direct child items within this book.
130      */
131     public function getDirectVisibleChildren(): Collection
132     {
133         $pages = $this->directPages()->scopes('visible')->get();
134         $chapters = $this->chapters()->scopes('visible')->get();
135
136         return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
137     }
138 }