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