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