1 <?php namespace BookStack\Entities\Repos;
3 use BookStack\Entities\Book;
4 use BookStack\Entities\Bookshelf;
5 use BookStack\Entities\Managers\TrashCan;
6 use BookStack\Exceptions\ImageUploadException;
7 use BookStack\Exceptions\NotFoundException;
9 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
10 use Illuminate\Http\UploadedFile;
11 use Illuminate\Support\Collection;
18 * BookshelfRepo constructor.
21 public function __construct(BaseRepo $baseRepo)
23 $this->baseRepo = $baseRepo;
27 * Get all bookshelves in a paginated format.
29 public function getAllPaginated(int $count = 20, string $sort = 'name', string $order = 'asc'): LengthAwarePaginator
31 return Bookshelf::visible()->with('visibleBooks')
32 ->orderBy($sort, $order)->paginate($count);
36 * Get the bookshelves that were most recently viewed by this user.
38 public function getRecentlyViewed(int $count = 20): Collection
40 return Bookshelf::visible()->withLastView()
41 ->having('last_viewed_at', '>', 0)
42 ->orderBy('last_viewed_at', 'desc')
43 ->take($count)->get();
47 * Get the most popular bookshelves in the system.
49 public function getPopular(int $count = 20): Collection
51 return Bookshelf::visible()->withViewCount()
52 ->having('view_count', '>', 0)
53 ->orderBy('view_count', 'desc')
54 ->take($count)->get();
58 * Get the most recently created bookshelves from the system.
60 public function getRecentlyCreated(int $count = 20): Collection
62 return Bookshelf::visible()->orderBy('created_at', 'desc')
63 ->take($count)->get();
67 * Get a shelf by its slug.
69 public function getBySlug(string $slug): Bookshelf
71 $shelf = Bookshelf::visible()->where('slug', '=', $slug)->first();
73 if ($shelf === null) {
74 throw new NotFoundException(trans('errors.bookshelf_not_found'));
81 * Create a new shelf in the system.
83 public function create(array $input, array $bookIds): Bookshelf
85 $shelf = new Bookshelf();
86 $this->baseRepo->create($shelf, $input);
87 $this->updateBooks($shelf, $bookIds);
92 * Create a new shelf in the system.
94 public function update(Bookshelf $shelf, array $input, array $bookIds): Bookshelf
96 $this->baseRepo->update($shelf, $input);
97 $this->updateBooks($shelf, $bookIds);
102 * Update which books are assigned to this shelf by
103 * syncing the given book ids.
104 * Function ensures the books are visible to the current user and existing.
106 protected function updateBooks(Bookshelf $shelf, array $bookIds)
108 $numericIDs = collect($bookIds)->map(function ($id) {
112 $syncData = Book::visible()
113 ->whereIn('id', $bookIds)
114 ->get(['id'])->pluck('id')->mapWithKeys(function ($bookId) use ($numericIDs) {
115 return [$bookId => ['order' => $numericIDs->search($bookId)]];
118 $shelf->books()->sync($syncData);
122 * Update the given shelf cover image, or clear it.
123 * @throws ImageUploadException
126 public function updateCoverImage(Bookshelf $shelf, UploadedFile $coverImage = null, bool $removeImage = false)
128 $this->baseRepo->updateCoverImage($shelf, $coverImage, $removeImage);
132 * Update the permissions of a bookshelf.
134 public function updatePermissions(Bookshelf $shelf, bool $restricted, Collection $permissions = null)
136 $this->baseRepo->updatePermissions($shelf, $restricted, $permissions);
140 * Copy down the permissions of the given shelf to all child books.
142 public function copyDownPermissions(Bookshelf $shelf): int
144 $shelfPermissions = $shelf->permissions()->get(['role_id', 'action'])->toArray();
145 $shelfBooks = $shelf->books()->get();
146 $updatedBookCount = 0;
148 /** @var Book $book */
149 foreach ($shelfBooks as $book) {
150 if (!userCan('restrictions-manage', $book)) {
153 $book->permissions()->delete();
154 $book->restricted = $shelf->restricted;
155 $book->permissions()->createMany($shelfPermissions);
157 $book->rebuildPermissions();
161 return $updatedBookCount;
165 * Remove a bookshelf from the system.
168 public function destroy(Bookshelf $shelf)
170 $trashCan = new TrashCan();
171 $trashCan->destroyShelf($shelf);