]> BookStack Code Mirror - bookstack/blob - app/Entities/Models/Bookshelf.php
Input WYSIWYG: Added reference store & fetch handling
[bookstack] / app / Entities / Models / Bookshelf.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
11 class Bookshelf extends Entity implements HasCoverImage
12 {
13     use HasFactory;
14     use HasHtmlDescription;
15
16     protected $table = 'bookshelves';
17
18     public float $searchFactor = 1.2;
19
20     protected $fillable = ['name', 'description', 'image_id'];
21
22     protected $hidden = ['image_id', 'deleted_at'];
23
24     /**
25      * Get the books in this shelf.
26      * Should not be used directly since does not take into account permissions.
27      *
28      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
29      */
30     public function books()
31     {
32         return $this->belongsToMany(Book::class, 'bookshelves_books', 'bookshelf_id', 'book_id')
33             ->withPivot('order')
34             ->orderBy('order', 'asc');
35     }
36
37     /**
38      * Related books that are visible to the current user.
39      */
40     public function visibleBooks(): BelongsToMany
41     {
42         return $this->books()->scopes('visible');
43     }
44
45     /**
46      * Get the url for this bookshelf.
47      */
48     public function getUrl(string $path = ''): string
49     {
50         return url('/shelves/' . implode('/', [urlencode($this->slug), trim($path, '/')]));
51     }
52
53     /**
54      * Returns shelf cover image, if cover not exists return default cover image.
55      */
56     public function getBookCover(int $width = 440, int $height = 250): string
57     {
58         // TODO - Make generic, focused on books right now, Perhaps set-up a better image
59         $default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
60         if (!$this->image_id || !$this->cover) {
61             return $default;
62         }
63
64         try {
65             return $this->cover->getThumb($width, $height, false) ?? $default;
66         } catch (Exception $err) {
67             return $default;
68         }
69     }
70
71     /**
72      * Get the cover image of the shelf.
73      */
74     public function cover(): BelongsTo
75     {
76         return $this->belongsTo(Image::class, 'image_id');
77     }
78
79     /**
80      * Get the type of the image model that is used when storing a cover image.
81      */
82     public function coverImageTypeKey(): string
83     {
84         return 'cover_bookshelf';
85     }
86
87     /**
88      * Check if this shelf contains the given book.
89      */
90     public function contains(Book $book): bool
91     {
92         return $this->books()->where('id', '=', $book->id)->count() > 0;
93     }
94
95     /**
96      * Add a book to the end of this shelf.
97      */
98     public function appendBook(Book $book)
99     {
100         if ($this->contains($book)) {
101             return;
102         }
103
104         $maxOrder = $this->books()->max('order');
105         $this->books()->attach($book->id, ['order' => $maxOrder + 1]);
106     }
107
108     /**
109      * Get a visible shelf by its slug.
110      * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
111      */
112     public static function getBySlug(string $slug): self
113     {
114         return static::visible()->where('slug', '=', $slug)->firstOrFail();
115     }
116 }