3 namespace BookStack\Http\Controllers;
5 use BookStack\Actions\View;
6 use BookStack\Entities\Models\Book;
7 use BookStack\Entities\Repos\ChapterRepo;
8 use BookStack\Entities\Tools\BookContents;
9 use BookStack\Entities\Tools\NextPreviousContentLocator;
10 use BookStack\Entities\Tools\PermissionsUpdater;
11 use BookStack\Exceptions\MoveOperationException;
12 use BookStack\Exceptions\NotFoundException;
13 use Illuminate\Http\Request;
14 use Illuminate\Validation\ValidationException;
17 class ChapterController extends Controller
19 protected $chapterRepo;
22 * ChapterController constructor.
24 public function __construct(ChapterRepo $chapterRepo)
26 $this->chapterRepo = $chapterRepo;
30 * Show the form for creating a new chapter.
32 public function create(string $bookSlug)
34 $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
35 $this->checkOwnablePermission('chapter-create', $book);
37 $this->setPageTitle(trans('entities.chapters_create'));
39 return view('chapters.create', ['book' => $book, 'current' => $book]);
43 * Store a newly created chapter in storage.
45 * @throws ValidationException
47 public function store(Request $request, string $bookSlug)
49 $this->validate($request, [
50 'name' => 'required|string|max:255',
53 $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
54 $this->checkOwnablePermission('chapter-create', $book);
56 $chapter = $this->chapterRepo->create($request->all(), $book);
58 return redirect($chapter->getUrl());
62 * Display the specified chapter.
64 public function show(string $bookSlug, string $chapterSlug)
66 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
67 $this->checkOwnablePermission('chapter-view', $chapter);
69 $sidebarTree = (new BookContents($chapter->book))->getTree();
70 $pages = $chapter->getVisiblePages();
71 $nextPreviousLocator = new NextPreviousContentLocator($chapter, $sidebarTree);
72 View::incrementFor($chapter);
74 $this->setPageTitle($chapter->getShortName());
76 return view('chapters.show', [
77 'book' => $chapter->book,
78 'chapter' => $chapter,
79 'current' => $chapter,
80 'sidebarTree' => $sidebarTree,
82 'next' => $nextPreviousLocator->getNext(),
83 'previous' => $nextPreviousLocator->getPrevious(),
88 * Show the form for editing the specified chapter.
90 public function edit(string $bookSlug, string $chapterSlug)
92 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
93 $this->checkOwnablePermission('chapter-update', $chapter);
95 $this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
97 return view('chapters.edit', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
101 * Update the specified chapter in storage.
103 * @throws NotFoundException
105 public function update(Request $request, string $bookSlug, string $chapterSlug)
107 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
108 $this->checkOwnablePermission('chapter-update', $chapter);
110 $this->chapterRepo->update($chapter, $request->all());
112 return redirect($chapter->getUrl());
116 * Shows the page to confirm deletion of this chapter.
118 * @throws NotFoundException
120 public function showDelete(string $bookSlug, string $chapterSlug)
122 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
123 $this->checkOwnablePermission('chapter-delete', $chapter);
125 $this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
127 return view('chapters.delete', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
131 * Remove the specified chapter from storage.
133 * @throws NotFoundException
136 public function destroy(string $bookSlug, string $chapterSlug)
138 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
139 $this->checkOwnablePermission('chapter-delete', $chapter);
141 $this->chapterRepo->destroy($chapter);
143 return redirect($chapter->book->getUrl());
147 * Show the page for moving a chapter.
149 * @throws NotFoundException
151 public function showMove(string $bookSlug, string $chapterSlug)
153 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
154 $this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
155 $this->checkOwnablePermission('chapter-update', $chapter);
156 $this->checkOwnablePermission('chapter-delete', $chapter);
158 return view('chapters.move', [
159 'chapter' => $chapter,
160 'book' => $chapter->book,
165 * Perform the move action for a chapter.
167 * @throws NotFoundException
169 public function move(Request $request, string $bookSlug, string $chapterSlug)
171 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
172 $this->checkOwnablePermission('chapter-update', $chapter);
173 $this->checkOwnablePermission('chapter-delete', $chapter);
175 $entitySelection = $request->get('entity_selection', null);
176 if ($entitySelection === null || $entitySelection === '') {
177 return redirect($chapter->getUrl());
181 $newBook = $this->chapterRepo->move($chapter, $entitySelection);
182 } catch (MoveOperationException $exception) {
183 $this->showErrorNotification(trans('errors.selected_book_not_found'));
185 return redirect()->back();
188 $this->showSuccessNotification(trans('entities.chapter_move_success', ['bookName' => $newBook->name]));
190 return redirect($chapter->getUrl());
194 * Show the Restrictions view.
196 * @throws NotFoundException
198 public function showPermissions(string $bookSlug, string $chapterSlug)
200 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
201 $this->checkOwnablePermission('restrictions-manage', $chapter);
203 return view('chapters.permissions', [
204 'chapter' => $chapter,
209 * Set the restrictions for this chapter.
211 * @throws NotFoundException
213 public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug, string $chapterSlug)
215 $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
216 $this->checkOwnablePermission('restrictions-manage', $chapter);
218 $permissionsUpdater->updateFromPermissionsForm($chapter, $request);
220 $this->showSuccessNotification(trans('entities.chapters_permissions_success'));
222 return redirect($chapter->getUrl());