1 <?php namespace BookStack\Http\Controllers;
5 use BookStack\Repos\EntityRepo;
6 use BookStack\Repos\UserRepo;
7 use BookStack\Services\ExportService;
8 use Illuminate\Http\Request;
9 use Illuminate\Http\Response;
12 class BookshelfController extends Controller
15 protected $entityRepo;
17 protected $exportService;
20 * BookController constructor.
21 * @param EntityRepo $entityRepo
22 * @param UserRepo $userRepo
23 * @param ExportService $exportService
25 public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
27 $this->entityRepo = $entityRepo;
28 $this->userRepo = $userRepo;
29 $this->exportService = $exportService;
30 parent::__construct();
34 * Display a listing of the book.
37 public function index()
39 $shelves = $this->entityRepo->getAllPaginated('bookshelf', 18);
40 $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('bookshelf', 4, 0) : false;
41 $popular = $this->entityRepo->getPopular('bookshelf', 4, 0);
42 $new = $this->entityRepo->getRecentlyCreated('bookshelf', 4, 0);
43 $shelvesViewType = setting()->getUser($this->currentUser, 'bookshelves_view_type', config('app.views.bookshelves', 'grid'));
44 $this->setPageTitle(trans('entities.shelves'));
45 return view('shelves/index', [
46 'shelves' => $shelves,
47 'recents' => $recents,
48 'popular' => $popular,
50 'shelvesViewType' => $shelvesViewType
55 * Show the form for creating a new bookshelf.
58 public function create()
60 $this->checkPermission('bookshelf-create-all');
61 $this->setPageTitle(trans('entities.shelves_create'));
62 $books = $this->entityRepo->getAll('book', false, 'update');
63 return view('shelves/create', ['books' => $books]);
67 * Store a newly created book in storage.
68 * @param Request $request
71 public function store(Request $request)
73 $this->checkPermission('bookshelf-create-all');
74 $this->validate($request, [
75 'name' => 'required|string|max:255',
76 'description' => 'string|max:1000',
79 $bookshelf = $this->entityRepo->createFromInput('bookshelf', $request->all());
80 $this->entityRepo->updateShelfBooks($bookshelf, $request->get('books', ''));
81 Activity::add($bookshelf, 'bookshelf_create');
83 return redirect($bookshelf->getUrl());
88 // * Display the specified book.
92 // public function show($slug)
94 // $book = $this->entityRepo->getBySlug('book', $slug);
95 // $this->checkOwnablePermission('book-view', $book);
96 // $bookChildren = $this->entityRepo->getBookChildren($book);
98 // $this->setPageTitle($book->getShortName());
99 // return view('books/show', [
101 // 'current' => $book,
102 // 'bookChildren' => $bookChildren,
103 // 'activity' => Activity::entityActivity($book, 20, 0)
108 // * Show the form for editing the specified book.
110 // * @return Response
112 // public function edit($slug)
114 // $book = $this->entityRepo->getBySlug('book', $slug);
115 // $this->checkOwnablePermission('book-update', $book);
116 // $this->setPageTitle(trans('entities.books_edit_named', ['bookName'=>$book->getShortName()]));
117 // return view('books/edit', ['book' => $book, 'current' => $book]);
121 // * Update the specified book in storage.
122 // * @param Request $request
124 // * @return Response
126 // public function update(Request $request, $slug)
128 // $book = $this->entityRepo->getBySlug('book', $slug);
129 // $this->checkOwnablePermission('book-update', $book);
130 // $this->validate($request, [
131 // 'name' => 'required|string|max:255',
132 // 'description' => 'string|max:1000'
134 // $book = $this->entityRepo->updateFromInput('book', $book, $request->all());
135 // Activity::add($book, 'book_update', $book->id);
136 // return redirect($book->getUrl());
140 // * Shows the page to confirm deletion
141 // * @param $bookSlug
142 // * @return \Illuminate\View\View
144 // public function showDelete($bookSlug)
146 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
147 // $this->checkOwnablePermission('book-delete', $book);
148 // $this->setPageTitle(trans('entities.books_delete_named', ['bookName'=>$book->getShortName()]));
149 // return view('books/delete', ['book' => $book, 'current' => $book]);
153 // * Shows the view which allows pages to be re-ordered and sorted.
154 // * @param string $bookSlug
155 // * @return \Illuminate\View\View
157 // public function sort($bookSlug)
159 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
160 // $this->checkOwnablePermission('book-update', $book);
161 // $bookChildren = $this->entityRepo->getBookChildren($book, true);
162 // $books = $this->entityRepo->getAll('book', false, 'update');
163 // $this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()]));
164 // return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
168 // * Shows the sort box for a single book.
169 // * Used via AJAX when loading in extra books to a sort.
170 // * @param $bookSlug
171 // * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
173 // public function getSortItem($bookSlug)
175 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
176 // $bookChildren = $this->entityRepo->getBookChildren($book);
177 // return view('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren]);
181 // * Saves an array of sort mapping to pages and chapters.
182 // * @param string $bookSlug
183 // * @param Request $request
184 // * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
186 // public function saveSort($bookSlug, Request $request)
188 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
189 // $this->checkOwnablePermission('book-update', $book);
191 // // Return if no map sent
192 // if (!$request->filled('sort-tree')) {
193 // return redirect($book->getUrl());
196 // // Sort pages and chapters
197 // $sortMap = collect(json_decode($request->get('sort-tree')));
198 // $bookIdsInvolved = collect([$book->id]);
200 // // Load models into map
201 // $sortMap->each(function ($mapItem) use ($bookIdsInvolved) {
202 // $mapItem->type = ($mapItem->type === 'page' ? 'page' : 'chapter');
203 // $mapItem->model = $this->entityRepo->getById($mapItem->type, $mapItem->id);
204 // // Store source and target books
205 // $bookIdsInvolved->push(intval($mapItem->model->book_id));
206 // $bookIdsInvolved->push(intval($mapItem->book));
209 // // Get the books involved in the sort
210 // $bookIdsInvolved = $bookIdsInvolved->unique()->toArray();
211 // $booksInvolved = $this->entityRepo->book->newQuery()->whereIn('id', $bookIdsInvolved)->get();
212 // // Throw permission error if invalid ids or inaccessible books given.
213 // if (count($bookIdsInvolved) !== count($booksInvolved)) {
214 // $this->showPermissionError();
216 // // Check permissions of involved books
217 // $booksInvolved->each(function (Book $book) {
218 // $this->checkOwnablePermission('book-update', $book);
221 // // Perform the sort
222 // $sortMap->each(function ($mapItem) {
223 // $model = $mapItem->model;
225 // $priorityChanged = intval($model->priority) !== intval($mapItem->sort);
226 // $bookChanged = intval($model->book_id) !== intval($mapItem->book);
227 // $chapterChanged = ($mapItem->type === 'page') && intval($model->chapter_id) !== $mapItem->parentChapter;
229 // if ($bookChanged) {
230 // $this->entityRepo->changeBook($mapItem->type, $mapItem->book, $model);
232 // if ($chapterChanged) {
233 // $model->chapter_id = intval($mapItem->parentChapter);
236 // if ($priorityChanged) {
237 // $model->priority = intval($mapItem->sort);
242 // // Rebuild permissions and add activity for involved books.
243 // $booksInvolved->each(function (Book $book) {
244 // $this->entityRepo->buildJointPermissionsForBook($book);
245 // Activity::add($book, 'book_sort', $book->id);
248 // return redirect($book->getUrl());
252 // * Remove the specified book from storage.
253 // * @param $bookSlug
254 // * @return Response
256 // public function destroy($bookSlug)
258 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
259 // $this->checkOwnablePermission('book-delete', $book);
260 // Activity::addMessage('book_delete', 0, $book->name);
261 // $this->entityRepo->destroyBook($book);
262 // return redirect('/books');
266 // * Show the Restrictions view.
267 // * @param $bookSlug
268 // * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
270 // public function showRestrict($bookSlug)
272 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
273 // $this->checkOwnablePermission('restrictions-manage', $book);
274 // $roles = $this->userRepo->getRestrictableRoles();
275 // return view('books/restrictions', [
282 // * Set the restrictions for this book.
283 // * @param $bookSlug
284 // * @param $bookSlug
285 // * @param Request $request
286 // * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
288 // public function restrict($bookSlug, Request $request)
290 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
291 // $this->checkOwnablePermission('restrictions-manage', $book);
292 // $this->entityRepo->updateEntityPermissionsFromRequest($request, $book);
293 // session()->flash('success', trans('entities.books_permissions_updated'));
294 // return redirect($book->getUrl());
298 // * Export a book as a PDF file.
299 // * @param string $bookSlug
302 // public function exportPdf($bookSlug)
304 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
305 // $pdfContent = $this->exportService->bookToPdf($book);
306 // return response()->make($pdfContent, 200, [
307 // 'Content-Type' => 'application/octet-stream',
308 // 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.pdf'
313 // * Export a book as a contained HTML file.
314 // * @param string $bookSlug
317 // public function exportHtml($bookSlug)
319 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
320 // $htmlContent = $this->exportService->bookToContainedHtml($book);
321 // return response()->make($htmlContent, 200, [
322 // 'Content-Type' => 'application/octet-stream',
323 // 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.html'
328 // * Export a book as a plain text file.
329 // * @param $bookSlug
332 // public function exportPlainText($bookSlug)
334 // $book = $this->entityRepo->getBySlug('book', $bookSlug);
335 // $htmlContent = $this->exportService->bookToPlainText($book);
336 // return response()->make($htmlContent, 200, [
337 // 'Content-Type' => 'application/octet-stream',
338 // 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.txt'