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