| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Entities\Repos; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-08 06:37:27 +08:00
										 |  |  | use BookStack\Actions\ActivityType; | 
					
						
							| 
									
										
										
										
											2020-11-22 08:17:45 +08:00
										 |  |  | use BookStack\Entities\Models\Book; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Bookshelf; | 
					
						
							| 
									
										
										
										
											2020-11-22 07:20:54 +08:00
										 |  |  | use BookStack\Entities\Tools\TrashCan; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | use BookStack\Exceptions\NotFoundException; | 
					
						
							| 
									
										
										
										
											2020-11-08 06:37:27 +08:00
										 |  |  | use BookStack\Facades\Activity; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | use Exception; | 
					
						
							|  |  |  | use Illuminate\Contracts\Pagination\LengthAwarePaginator; | 
					
						
							|  |  |  | use Illuminate\Support\Collection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BookshelfRepo | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     protected $baseRepo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * BookshelfRepo constructor. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function __construct(BaseRepo $baseRepo) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->baseRepo = $baseRepo; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get all bookshelves in a paginated format. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getAllPaginated(int $count = 20, string $sort = 'name', string $order = 'asc'): LengthAwarePaginator | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-05-13 05:21:45 +08:00
										 |  |  |         return Bookshelf::visible() | 
					
						
							| 
									
										
										
										
											2021-01-11 07:12:51 +08:00
										 |  |  |             ->with(['visibleBooks', 'cover']) | 
					
						
							| 
									
										
										
										
											2020-05-13 05:21:45 +08:00
										 |  |  |             ->orderBy($sort, $order) | 
					
						
							|  |  |  |             ->paginate($count); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the bookshelves that were most recently viewed by this user. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getRecentlyViewed(int $count = 20): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return Bookshelf::visible()->withLastView() | 
					
						
							|  |  |  |             ->having('last_viewed_at', '>', 0) | 
					
						
							|  |  |  |             ->orderBy('last_viewed_at', 'desc') | 
					
						
							|  |  |  |             ->take($count)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the most popular bookshelves in the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getPopular(int $count = 20): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return Bookshelf::visible()->withViewCount() | 
					
						
							|  |  |  |             ->having('view_count', '>', 0) | 
					
						
							|  |  |  |             ->orderBy('view_count', 'desc') | 
					
						
							|  |  |  |             ->take($count)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the most recently created bookshelves from the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getRecentlyCreated(int $count = 20): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return Bookshelf::visible()->orderBy('created_at', 'desc') | 
					
						
							|  |  |  |             ->take($count)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a shelf by its slug. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getBySlug(string $slug): Bookshelf | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $shelf = Bookshelf::visible()->where('slug', '=', $slug)->first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($shelf === null) { | 
					
						
							|  |  |  |             throw new NotFoundException(trans('errors.bookshelf_not_found')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $shelf; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Create a new shelf in the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function create(array $input, array $bookIds): Bookshelf | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $shelf = new Bookshelf(); | 
					
						
							|  |  |  |         $this->baseRepo->create($shelf, $input); | 
					
						
							| 
									
										
										
										
											2022-06-15 22:05:08 +08:00
										 |  |  |         $this->baseRepo->updateCoverImage($shelf, $input['image'] ?? null); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         $this->updateBooks($shelf, $bookIds); | 
					
						
							| 
									
										
										
										
											2021-12-12 01:29:33 +08:00
										 |  |  |         Activity::add(ActivityType::BOOKSHELF_CREATE, $shelf); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         return $shelf; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2020-11-08 06:37:27 +08:00
										 |  |  |      * Update an existing shelf in the system using the given input. | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-04-10 22:19:18 +08:00
										 |  |  |     public function update(Bookshelf $shelf, array $input, ?array $bookIds): Bookshelf | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->baseRepo->update($shelf, $input); | 
					
						
							| 
									
										
										
										
											2020-04-10 22:19:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!is_null($bookIds)) { | 
					
						
							|  |  |  |             $this->updateBooks($shelf, $bookIds); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-15 22:05:08 +08:00
										 |  |  |         if (array_key_exists('image', $input)) { | 
					
						
							| 
									
										
										
										
											2022-06-14 00:20:21 +08:00
										 |  |  |             $this->baseRepo->updateCoverImage($shelf, $input['image'], $input['image'] === null); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 01:29:33 +08:00
										 |  |  |         Activity::add(ActivityType::BOOKSHELF_UPDATE, $shelf); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         return $shelf; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-06-14 00:20:21 +08:00
										 |  |  |      * Update which books are assigned to this shelf by syncing the given book ids. | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      * Function ensures the books are visible to the current user and existing. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateBooks(Bookshelf $shelf, array $bookIds) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $numericIDs = collect($bookIds)->map(function ($id) { | 
					
						
							|  |  |  |             return intval($id); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $syncData = Book::visible() | 
					
						
							|  |  |  |             ->whereIn('id', $bookIds) | 
					
						
							| 
									
										
										
										
											2021-11-06 00:18:06 +08:00
										 |  |  |             ->pluck('id') | 
					
						
							|  |  |  |             ->mapWithKeys(function ($bookId) use ($numericIDs) { | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |                 return [$bookId => ['order' => $numericIDs->search($bookId)]]; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $shelf->books()->sync($syncData); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove a bookshelf from the system. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function destroy(Bookshelf $shelf) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $trashCan = new TrashCan(); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         $trashCan->softDestroyShelf($shelf); | 
					
						
							| 
									
										
										
										
											2021-12-12 01:29:33 +08:00
										 |  |  |         Activity::add(ActivityType::BOOKSHELF_DELETE, $shelf); | 
					
						
							| 
									
										
										
										
											2020-11-07 21:58:23 +08:00
										 |  |  |         $trashCan->autoClearOld(); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } |