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