]> BookStack Code Mirror - bookstack/blob - app/Entities/Models/Bookshelf.php
Fixed some mis-refactoring and split search service
[bookstack] / app / Entities / Models / Bookshelf.php
1 <?php namespace BookStack\Entities\Models;
2
3 use BookStack\Entities\Models\Entity;
4 use BookStack\Entities\Models\HasCoverImage;
5 use BookStack\Entities\Models\Book;
6 use BookStack\Uploads\Image;
7 use Illuminate\Database\Eloquent\Relations\BelongsTo;
8 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9
10 class Bookshelf extends Entity implements HasCoverImage
11 {
12     protected $table = 'bookshelves';
13
14     public $searchFactor = 3;
15
16     protected $fillable = ['name', 'description', 'image_id'];
17
18     protected $hidden = ['restricted', 'image_id'];
19
20     /**
21      * Get the books in this shelf.
22      * Should not be used directly since does not take into account permissions.
23      * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
24      */
25     public function books()
26     {
27         return $this->belongsToMany(Book::class, 'bookshelves_books', 'bookshelf_id', 'book_id')
28             ->withPivot('order')
29             ->orderBy('order', 'asc');
30     }
31
32     /**
33      * Related books that are visible to the current user.
34      */
35     public function visibleBooks(): BelongsToMany
36     {
37         return $this->books()->visible();
38     }
39
40     /**
41      * Get the url for this bookshelf.
42      * @param string|bool $path
43      * @return string
44      */
45     public function getUrl($path = false)
46     {
47         if ($path !== false) {
48             return url('/shelves/' . urlencode($this->slug) . '/' . trim($path, '/'));
49         }
50         return url('/shelves/' . urlencode($this->slug));
51     }
52
53     /**
54      * Returns BookShelf cover image, if cover does not exists return default cover image.
55      * @param int $width - Width of the image
56      * @param int $height - Height of the image
57      * @return string
58      */
59     public function getBookCover($width = 440, $height = 250)
60     {
61         // TODO - Make generic, focused on books right now, Perhaps set-up a better image
62         $default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
63         if (!$this->image_id) {
64             return $default;
65         }
66
67         try {
68             $cover = $this->cover ? url($this->cover->getThumb($width, $height, false)) : $default;
69         } catch (\Exception $err) {
70             $cover = $default;
71         }
72         return $cover;
73     }
74
75     /**
76      * Get the cover image of the shelf
77      */
78     public function cover(): BelongsTo
79     {
80         return $this->belongsTo(Image::class, 'image_id');
81     }
82
83     /**
84      * Get the type of the image model that is used when storing a cover image.
85      */
86     public function coverImageTypeKey(): string
87     {
88         return 'cover_shelf';
89     }
90
91     /**
92      * Get an excerpt of this book's description to the specified length or less.
93      * @param int $length
94      * @return string
95      */
96     public function getExcerpt(int $length = 100)
97     {
98         $description = $this->description;
99         return mb_strlen($description) > $length ? mb_substr($description, 0, $length-3) . '...' : $description;
100     }
101
102     /**
103      * Check if this shelf contains the given book.
104      * @param Book $book
105      * @return bool
106      */
107     public function contains(Book $book): bool
108     {
109         return $this->books()->where('id', '=', $book->id)->count() > 0;
110     }
111
112     /**
113      * Add a book to the end of this shelf.
114      * @param Book $book
115      */
116     public function appendBook(Book $book)
117     {
118         if ($this->contains($book)) {
119             return;
120         }
121
122         $maxOrder = $this->books()->max('order');
123         $this->books()->attach($book->id, ['order' => $maxOrder + 1]);
124     }
125 }