]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/BookshelfController.php
Thumbnails: Fixed thumnail orientation
[bookstack] / app / Entities / Controllers / BookshelfController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Activity\ActivityQueries;
6 use BookStack\Activity\Models\View;
7 use BookStack\Entities\Queries\BookQueries;
8 use BookStack\Entities\Queries\BookshelfQueries;
9 use BookStack\Entities\Repos\BookshelfRepo;
10 use BookStack\Entities\Tools\ShelfContext;
11 use BookStack\Exceptions\ImageUploadException;
12 use BookStack\Exceptions\NotFoundException;
13 use BookStack\Http\Controller;
14 use BookStack\References\ReferenceFetcher;
15 use BookStack\Util\SimpleListOptions;
16 use Exception;
17 use Illuminate\Http\Request;
18 use Illuminate\Validation\ValidationException;
19
20 class BookshelfController extends Controller
21 {
22     public function __construct(
23         protected BookshelfRepo $shelfRepo,
24         protected BookshelfQueries $queries,
25         protected BookQueries $bookQueries,
26         protected ShelfContext $shelfContext,
27         protected ReferenceFetcher $referenceFetcher,
28     ) {
29     }
30
31     /**
32      * Display a listing of bookshelves.
33      */
34     public function index(Request $request)
35     {
36         $view = setting()->getForCurrentUser('bookshelves_view_type');
37         $listOptions = SimpleListOptions::fromRequest($request, 'bookshelves')->withSortOptions([
38             'name'       => trans('common.sort_name'),
39             'created_at' => trans('common.sort_created_at'),
40             'updated_at' => trans('common.sort_updated_at'),
41         ]);
42
43         $shelves = $this->queries->visibleForListWithCover()
44             ->orderBy($listOptions->getSort(), $listOptions->getOrder())
45             ->paginate(18);
46         $recents = $this->isSignedIn() ? $this->queries->recentlyViewedForCurrentUser()->get() : false;
47         $popular = $this->queries->popularForList()->get();
48         $new = $this->queries->visibleForList()
49             ->orderBy('created_at', 'desc')
50             ->take(4)
51             ->get();
52
53         $this->shelfContext->clearShelfContext();
54         $this->setPageTitle(trans('entities.shelves'));
55
56         return view('shelves.index', [
57             'shelves'     => $shelves,
58             'recents'     => $recents,
59             'popular'     => $popular,
60             'new'         => $new,
61             'view'        => $view,
62             'listOptions' => $listOptions,
63         ]);
64     }
65
66     /**
67      * Show the form for creating a new bookshelf.
68      */
69     public function create()
70     {
71         $this->checkPermission('bookshelf-create-all');
72         $books = $this->bookQueries->visibleForList()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
73         $this->setPageTitle(trans('entities.shelves_create'));
74
75         return view('shelves.create', ['books' => $books]);
76     }
77
78     /**
79      * Store a newly created bookshelf in storage.
80      *
81      * @throws ValidationException
82      * @throws ImageUploadException
83      */
84     public function store(Request $request)
85     {
86         $this->checkPermission('bookshelf-create-all');
87         $validated = $this->validate($request, [
88             'name'             => ['required', 'string', 'max:255'],
89             'description_html' => ['string', 'max:2000'],
90             'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
91             'tags'             => ['array'],
92         ]);
93
94         $bookIds = explode(',', $request->get('books', ''));
95         $shelf = $this->shelfRepo->create($validated, $bookIds);
96
97         return redirect($shelf->getUrl());
98     }
99
100     /**
101      * Display the bookshelf of the given slug.
102      *
103      * @throws NotFoundException
104      */
105     public function show(Request $request, ActivityQueries $activities, string $slug)
106     {
107         $shelf = $this->queries->findVisibleBySlugOrFail($slug);
108         $this->checkOwnablePermission('bookshelf-view', $shelf);
109
110         $listOptions = SimpleListOptions::fromRequest($request, 'shelf_books')->withSortOptions([
111             'default' => trans('common.sort_default'),
112             'name' => trans('common.sort_name'),
113             'created_at' => trans('common.sort_created_at'),
114             'updated_at' => trans('common.sort_updated_at'),
115         ]);
116
117         $sort = $listOptions->getSort();
118         $sortedVisibleShelfBooks = $shelf->visibleBooks()
119             ->reorder($sort === 'default' ? 'order' : $sort, $listOptions->getOrder())
120             ->get()
121             ->values()
122             ->all();
123
124         View::incrementFor($shelf);
125         $this->shelfContext->setShelfContext($shelf->id);
126         $view = setting()->getForCurrentUser('bookshelf_view_type');
127
128         $this->setPageTitle($shelf->getShortName());
129
130         return view('shelves.show', [
131             'shelf'                   => $shelf,
132             'sortedVisibleShelfBooks' => $sortedVisibleShelfBooks,
133             'view'                    => $view,
134             'activity'                => $activities->entityActivity($shelf, 20, 1),
135             'listOptions'             => $listOptions,
136             'referenceCount'          => $this->referenceFetcher->getReferenceCountToEntity($shelf),
137         ]);
138     }
139
140     /**
141      * Show the form for editing the specified bookshelf.
142      */
143     public function edit(string $slug)
144     {
145         $shelf = $this->queries->findVisibleBySlugOrFail($slug);
146         $this->checkOwnablePermission('bookshelf-update', $shelf);
147
148         $shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
149         $books = $this->bookQueries->visibleForList()
150             ->whereNotIn('id', $shelfBookIds)
151             ->orderBy('name')
152             ->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
153
154         $this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $shelf->getShortName()]));
155
156         return view('shelves.edit', [
157             'shelf' => $shelf,
158             'books' => $books,
159         ]);
160     }
161
162     /**
163      * Update the specified bookshelf in storage.
164      *
165      * @throws ValidationException
166      * @throws ImageUploadException
167      * @throws NotFoundException
168      */
169     public function update(Request $request, string $slug)
170     {
171         $shelf = $this->queries->findVisibleBySlugOrFail($slug);
172         $this->checkOwnablePermission('bookshelf-update', $shelf);
173         $validated = $this->validate($request, [
174             'name'             => ['required', 'string', 'max:255'],
175             'description_html' => ['string', 'max:2000'],
176             'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
177             'tags'             => ['array'],
178         ]);
179
180         if ($request->has('image_reset')) {
181             $validated['image'] = null;
182         } elseif (array_key_exists('image', $validated) && is_null($validated['image'])) {
183             unset($validated['image']);
184         }
185
186         $bookIds = explode(',', $request->get('books', ''));
187         $shelf = $this->shelfRepo->update($shelf, $validated, $bookIds);
188
189         return redirect($shelf->getUrl());
190     }
191
192     /**
193      * Shows the page to confirm deletion.
194      */
195     public function showDelete(string $slug)
196     {
197         $shelf = $this->queries->findVisibleBySlugOrFail($slug);
198         $this->checkOwnablePermission('bookshelf-delete', $shelf);
199
200         $this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()]));
201
202         return view('shelves.delete', ['shelf' => $shelf]);
203     }
204
205     /**
206      * Remove the specified bookshelf from storage.
207      *
208      * @throws Exception
209      */
210     public function destroy(string $slug)
211     {
212         $shelf = $this->queries->findVisibleBySlugOrFail($slug);
213         $this->checkOwnablePermission('bookshelf-delete', $shelf);
214
215         $this->shelfRepo->destroy($shelf);
216
217         return redirect('/shelves');
218     }
219 }