]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/ChapterApiController.php
Fix Dark theme
[bookstack] / app / Entities / Controllers / ChapterApiController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Chapter;
7 use BookStack\Entities\Repos\ChapterRepo;
8 use BookStack\Exceptions\PermissionsException;
9 use BookStack\Http\ApiController;
10 use Exception;
11 use Illuminate\Database\Eloquent\Relations\HasMany;
12 use Illuminate\Http\Request;
13
14 class ChapterApiController extends ApiController
15 {
16     protected $rules = [
17         'create' => [
18             'book_id'     => ['required', 'integer'],
19             'name'        => ['required', 'string', 'max:255'],
20             'description' => ['string', 'max:1000'],
21             'tags'        => ['array'],
22         ],
23         'update' => [
24             'book_id'     => ['integer'],
25             'name'        => ['string', 'min:1', 'max:255'],
26             'description' => ['string', 'max:1000'],
27             'tags'        => ['array'],
28         ],
29     ];
30
31     public function __construct(
32         protected ChapterRepo $chapterRepo
33     ) {
34     }
35
36     /**
37      * Get a listing of chapters visible to the user.
38      */
39     public function list()
40     {
41         $chapters = Chapter::visible();
42
43         return $this->apiListingResponse($chapters, [
44             'id', 'book_id', 'name', 'slug', 'description', 'priority',
45             'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by',
46         ]);
47     }
48
49     /**
50      * Create a new chapter in the system.
51      */
52     public function create(Request $request)
53     {
54         $requestData = $this->validate($request, $this->rules['create']);
55
56         $bookId = $request->get('book_id');
57         $book = Book::visible()->findOrFail($bookId);
58         $this->checkOwnablePermission('chapter-create', $book);
59
60         $chapter = $this->chapterRepo->create($requestData, $book);
61
62         return response()->json($chapter->load(['tags']));
63     }
64
65     /**
66      * View the details of a single chapter.
67      */
68     public function read(string $id)
69     {
70         $chapter = Chapter::visible()->with(['tags', 'createdBy', 'updatedBy', 'ownedBy', 'pages' => function (HasMany $query) {
71             $query->scopes('visible')->get(['id', 'name', 'slug']);
72         }])->findOrFail($id);
73
74         return response()->json($chapter);
75     }
76
77     /**
78      * Update the details of a single chapter.
79      * Providing a 'book_id' property will essentially move the chapter
80      * into that parent element if you have permissions to do so.
81      */
82     public function update(Request $request, string $id)
83     {
84         $requestData = $this->validate($request, $this->rules()['update']);
85         $chapter = Chapter::visible()->findOrFail($id);
86         $this->checkOwnablePermission('chapter-update', $chapter);
87
88         if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) {
89             $this->checkOwnablePermission('chapter-delete', $chapter);
90
91             try {
92                 $this->chapterRepo->move($chapter, "book:{$requestData['book_id']}");
93             } catch (Exception $exception) {
94                 if ($exception instanceof  PermissionsException) {
95                     $this->showPermissionError();
96                 }
97
98                 return $this->jsonError(trans('errors.selected_book_not_found'));
99             }
100         }
101
102         $updatedChapter = $this->chapterRepo->update($chapter, $requestData);
103
104         return response()->json($updatedChapter->load(['tags']));
105     }
106
107     /**
108      * Delete a chapter.
109      * This will typically send the chapter to the recycle bin.
110      */
111     public function delete(string $id)
112     {
113         $chapter = Chapter::visible()->findOrFail($id);
114         $this->checkOwnablePermission('chapter-delete', $chapter);
115
116         $this->chapterRepo->destroy($chapter);
117
118         return response('', 204);
119     }
120 }