]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/ChapterController.php
Merge branch 'v0.30.x'
[bookstack] / app / Http / Controllers / ChapterController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Entities\Models\Book;
4 use BookStack\Entities\Tools\BookContents;
5 use BookStack\Entities\Repos\ChapterRepo;
6 use BookStack\Exceptions\MoveOperationException;
7 use BookStack\Exceptions\NotFoundException;
8 use Illuminate\Http\Request;
9 use Illuminate\Validation\ValidationException;
10 use Throwable;
11 use Views;
12
13 class ChapterController extends Controller
14 {
15
16     protected $chapterRepo;
17
18     /**
19      * ChapterController constructor.
20      */
21     public function __construct(ChapterRepo $chapterRepo)
22     {
23         $this->chapterRepo = $chapterRepo;
24     }
25
26     /**
27      * Show the form for creating a new chapter.
28      */
29     public function create(string $bookSlug)
30     {
31         $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
32         $this->checkOwnablePermission('chapter-create', $book);
33
34         $this->setPageTitle(trans('entities.chapters_create'));
35         return view('chapters.create', ['book' => $book, 'current' => $book]);
36     }
37
38     /**
39      * Store a newly created chapter in storage.
40      * @throws ValidationException
41      */
42     public function store(Request $request, string $bookSlug)
43     {
44         $this->validate($request, [
45             'name' => 'required|string|max:255'
46         ]);
47
48         $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
49         $this->checkOwnablePermission('chapter-create', $book);
50
51         $chapter = $this->chapterRepo->create($request->all(), $book);
52
53         return redirect($chapter->getUrl());
54     }
55
56     /**
57      * Display the specified chapter.
58      */
59     public function show(string $bookSlug, string $chapterSlug)
60     {
61         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
62         $this->checkOwnablePermission('chapter-view', $chapter);
63
64         $sidebarTree = (new BookContents($chapter->book))->getTree();
65         $pages = $chapter->getVisiblePages();
66         Views::add($chapter);
67
68         $this->setPageTitle($chapter->getShortName());
69         return view('chapters.show', [
70             'book' => $chapter->book,
71             'chapter' => $chapter,
72             'current' => $chapter,
73             'sidebarTree' => $sidebarTree,
74             'pages' => $pages
75         ]);
76     }
77
78     /**
79      * Show the form for editing the specified chapter.
80      */
81     public function edit(string $bookSlug, string $chapterSlug)
82     {
83         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
84         $this->checkOwnablePermission('chapter-update', $chapter);
85
86         $this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
87         return view('chapters.edit', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
88     }
89
90     /**
91      * Update the specified chapter in storage.
92      * @throws NotFoundException
93      */
94     public function update(Request $request, string $bookSlug, string $chapterSlug)
95     {
96         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
97         $this->checkOwnablePermission('chapter-update', $chapter);
98
99         $this->chapterRepo->update($chapter, $request->all());
100
101         return redirect($chapter->getUrl());
102     }
103
104     /**
105      * Shows the page to confirm deletion of this chapter.
106      * @throws NotFoundException
107      */
108     public function showDelete(string $bookSlug, string $chapterSlug)
109     {
110         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
111         $this->checkOwnablePermission('chapter-delete', $chapter);
112
113         $this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
114         return view('chapters.delete', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
115     }
116
117     /**
118      * Remove the specified chapter from storage.
119      * @throws NotFoundException
120      * @throws Throwable
121      */
122     public function destroy(string $bookSlug, string $chapterSlug)
123     {
124         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
125         $this->checkOwnablePermission('chapter-delete', $chapter);
126
127         $this->chapterRepo->destroy($chapter);
128
129         return redirect($chapter->book->getUrl());
130     }
131
132     /**
133      * Show the page for moving a chapter.
134      * @throws NotFoundException
135      */
136     public function showMove(string $bookSlug, string $chapterSlug)
137     {
138         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
139         $this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
140         $this->checkOwnablePermission('chapter-update', $chapter);
141         $this->checkOwnablePermission('chapter-delete', $chapter);
142
143         return view('chapters.move', [
144             'chapter' => $chapter,
145             'book' => $chapter->book
146         ]);
147     }
148
149     /**
150      * Perform the move action for a chapter.
151      * @throws NotFoundException
152      */
153     public function move(Request $request, string $bookSlug, string $chapterSlug)
154     {
155         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
156         $this->checkOwnablePermission('chapter-update', $chapter);
157         $this->checkOwnablePermission('chapter-delete', $chapter);
158
159         $entitySelection = $request->get('entity_selection', null);
160         if ($entitySelection === null || $entitySelection === '') {
161             return redirect($chapter->getUrl());
162         }
163
164         try {
165             $newBook = $this->chapterRepo->move($chapter, $entitySelection);
166         } catch (MoveOperationException $exception) {
167             $this->showErrorNotification(trans('errors.selected_book_not_found'));
168             return redirect()->back();
169         }
170
171         $this->showSuccessNotification(trans('entities.chapter_move_success', ['bookName' => $newBook->name]));
172         return redirect($chapter->getUrl());
173     }
174
175     /**
176      * Show the Restrictions view.
177      * @throws NotFoundException
178      */
179     public function showPermissions(string $bookSlug, string $chapterSlug)
180     {
181         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
182         $this->checkOwnablePermission('restrictions-manage', $chapter);
183
184         return view('chapters.permissions', [
185             'chapter' => $chapter,
186         ]);
187     }
188
189     /**
190      * Set the restrictions for this chapter.
191      * @throws NotFoundException
192      */
193     public function permissions(Request $request, string $bookSlug, string $chapterSlug)
194     {
195         $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
196         $this->checkOwnablePermission('restrictions-manage', $chapter);
197
198         $restricted = $request->get('restricted') === 'true';
199         $permissions = $request->filled('restrictions') ? collect($request->get('restrictions')) : null;
200         $this->chapterRepo->updatePermissions($chapter, $restricted, $permissions);
201
202         $this->showSuccessNotification(trans('entities.chapters_permissions_success'));
203         return redirect($chapter->getUrl());
204     }
205 }