]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/BookController.php
Merge branch 'v0.30.x'
[bookstack] / app / Http / Controllers / BookController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use Activity;
4 use BookStack\Actions\ActivityType;
5 use BookStack\Entities\Tools\BookContents;
6 use BookStack\Entities\Models\Bookshelf;
7 use BookStack\Entities\Tools\ShelfContext;
8 use BookStack\Entities\Repos\BookRepo;
9 use BookStack\Exceptions\ImageUploadException;
10 use Illuminate\Http\Request;
11 use Illuminate\Validation\ValidationException;
12 use Throwable;
13 use Views;
14
15 class BookController extends Controller
16 {
17
18     protected $bookRepo;
19     protected $entityContextManager;
20
21     public function __construct(ShelfContext $entityContextManager, BookRepo $bookRepo)
22     {
23         $this->bookRepo = $bookRepo;
24         $this->entityContextManager = $entityContextManager;
25     }
26
27     /**
28      * Display a listing of the book.
29      */
30     public function index()
31     {
32         $view = setting()->getForCurrentUser('books_view_type', config('app.views.books'));
33         $sort = setting()->getForCurrentUser('books_sort', 'name');
34         $order = setting()->getForCurrentUser('books_sort_order', 'asc');
35
36         $books = $this->bookRepo->getAllPaginated(18, $sort, $order);
37         $recents = $this->isSignedIn() ? $this->bookRepo->getRecentlyViewed(4) : false;
38         $popular = $this->bookRepo->getPopular(4);
39         $new = $this->bookRepo->getRecentlyCreated(4);
40
41         $this->entityContextManager->clearShelfContext();
42
43         $this->setPageTitle(trans('entities.books'));
44         return view('books.index', [
45             'books' => $books,
46             'recents' => $recents,
47             'popular' => $popular,
48             'new' => $new,
49             'view' => $view,
50             'sort' => $sort,
51             'order' => $order,
52         ]);
53     }
54
55     /**
56      * Show the form for creating a new book.
57      */
58     public function create(string $shelfSlug = null)
59     {
60         $this->checkPermission('book-create-all');
61
62         $bookshelf = null;
63         if ($shelfSlug !== null) {
64             $bookshelf = Bookshelf::visible()->where('slug', '=', $shelfSlug)->firstOrFail();
65             $this->checkOwnablePermission('bookshelf-update', $bookshelf);
66         }
67
68         $this->setPageTitle(trans('entities.books_create'));
69         return view('books.create', [
70             'bookshelf' => $bookshelf
71         ]);
72     }
73
74     /**
75      * Store a newly created book in storage.
76      * @throws ImageUploadException
77      * @throws ValidationException
78      */
79     public function store(Request $request, string $shelfSlug = null)
80     {
81         $this->checkPermission('book-create-all');
82         $this->validate($request, [
83             'name' => 'required|string|max:255',
84             'description' => 'string|max:1000',
85             'image' => 'nullable|' . $this->getImageValidationRules(),
86         ]);
87
88         $bookshelf = null;
89         if ($shelfSlug !== null) {
90             $bookshelf = Bookshelf::visible()->where('slug', '=', $shelfSlug)->firstOrFail();
91             $this->checkOwnablePermission('bookshelf-update', $bookshelf);
92         }
93
94         $book = $this->bookRepo->create($request->all());
95         $this->bookRepo->updateCoverImage($book, $request->file('image', null));
96
97         if ($bookshelf) {
98             $bookshelf->appendBook($book);
99             Activity::addForEntity($bookshelf, ActivityType::BOOKSHELF_UPDATE);
100         }
101
102         return redirect($book->getUrl());
103     }
104
105     /**
106      * Display the specified book.
107      */
108     public function show(Request $request, string $slug)
109     {
110         $book = $this->bookRepo->getBySlug($slug);
111         $bookChildren = (new BookContents($book))->getTree(true);
112         $bookParentShelves = $book->shelves()->visible()->get();
113
114         Views::add($book);
115         if ($request->has('shelf')) {
116             $this->entityContextManager->setShelfContext(intval($request->get('shelf')));
117         }
118
119         $this->setPageTitle($book->getShortName());
120         return view('books.show', [
121             'book' => $book,
122             'current' => $book,
123             'bookChildren' => $bookChildren,
124             'bookParentShelves' => $bookParentShelves,
125             'activity' => Activity::entityActivity($book, 20, 1)
126         ]);
127     }
128
129     /**
130      * Show the form for editing the specified book.
131      */
132     public function edit(string $slug)
133     {
134         $book = $this->bookRepo->getBySlug($slug);
135         $this->checkOwnablePermission('book-update', $book);
136         $this->setPageTitle(trans('entities.books_edit_named', ['bookName'=>$book->getShortName()]));
137         return view('books.edit', ['book' => $book, 'current' => $book]);
138     }
139
140     /**
141      * Update the specified book in storage.
142      * @throws ImageUploadException
143      * @throws ValidationException
144      * @throws Throwable
145      */
146     public function update(Request $request, string $slug)
147     {
148         $book = $this->bookRepo->getBySlug($slug);
149         $this->checkOwnablePermission('book-update', $book);
150         $this->validate($request, [
151             'name' => 'required|string|max:255',
152             'description' => 'string|max:1000',
153             'image' => 'nullable|' . $this->getImageValidationRules(),
154         ]);
155
156         $book = $this->bookRepo->update($book, $request->all());
157         $resetCover = $request->has('image_reset');
158         $this->bookRepo->updateCoverImage($book, $request->file('image', null), $resetCover);
159
160         return redirect($book->getUrl());
161     }
162
163     /**
164      * Shows the page to confirm deletion.
165      */
166     public function showDelete(string $bookSlug)
167     {
168         $book = $this->bookRepo->getBySlug($bookSlug);
169         $this->checkOwnablePermission('book-delete', $book);
170         $this->setPageTitle(trans('entities.books_delete_named', ['bookName' => $book->getShortName()]));
171         return view('books.delete', ['book' => $book, 'current' => $book]);
172     }
173
174     /**
175      * Remove the specified book from the system.
176      * @throws Throwable
177      */
178     public function destroy(string $bookSlug)
179     {
180         $book = $this->bookRepo->getBySlug($bookSlug);
181         $this->checkOwnablePermission('book-delete', $book);
182
183         $this->bookRepo->destroy($book);
184
185         return redirect('/books');
186     }
187
188     /**
189      * Show the permissions view.
190      */
191     public function showPermissions(string $bookSlug)
192     {
193         $book = $this->bookRepo->getBySlug($bookSlug);
194         $this->checkOwnablePermission('restrictions-manage', $book);
195
196         return view('books.permissions', [
197             'book' => $book,
198         ]);
199     }
200
201     /**
202      * Set the restrictions for this book.
203      * @throws Throwable
204      */
205     public function permissions(Request $request, string $bookSlug)
206     {
207         $book = $this->bookRepo->getBySlug($bookSlug);
208         $this->checkOwnablePermission('restrictions-manage', $book);
209
210         $restricted = $request->get('restricted') === 'true';
211         $permissions = $request->filled('restrictions') ? collect($request->get('restrictions')) : null;
212         $this->bookRepo->updatePermissions($book, $restricted, $permissions);
213
214         $this->showSuccessNotification(trans('entities.books_permissions_updated'));
215         return redirect($book->getUrl());
216     }
217 }