| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Entities\Controllers; | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 08:17:45 +08:00
										 |  |  | use BookStack\Entities\Models\Chapter; | 
					
						
							| 
									
										
										
										
											2024-02-08 00:37:36 +08:00
										 |  |  | use BookStack\Entities\Queries\ChapterQueries; | 
					
						
							| 
									
										
										
										
											2024-02-11 23:42:37 +08:00
										 |  |  | use BookStack\Entities\Queries\EntityQueries; | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  | use BookStack\Entities\Repos\ChapterRepo; | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  | use BookStack\Exceptions\PermissionsException; | 
					
						
							| 
									
										
										
										
											2023-05-19 03:53:39 +08:00
										 |  |  | use BookStack\Http\ApiController; | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  | use Exception; | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Relations\HasMany; | 
					
						
							|  |  |  | use Illuminate\Http\Request; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChapterApiController extends ApiController | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     protected $rules = [ | 
					
						
							|  |  |  |         'create' => [ | 
					
						
							| 
									
										
										
										
											2024-01-30 02:59:03 +08:00
										 |  |  |             'book_id'             => ['required', 'integer'], | 
					
						
							|  |  |  |             'name'                => ['required', 'string', 'max:255'], | 
					
						
							|  |  |  |             'description'         => ['string', 'max:1900'], | 
					
						
							|  |  |  |             'description_html'    => ['string', 'max:2000'], | 
					
						
							|  |  |  |             'tags'                => ['array'], | 
					
						
							|  |  |  |             'priority'            => ['integer'], | 
					
						
							|  |  |  |             'default_template_id' => ['nullable', 'integer'], | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         ], | 
					
						
							|  |  |  |         'update' => [ | 
					
						
							| 
									
										
										
										
											2024-01-30 02:59:03 +08:00
										 |  |  |             'book_id'             => ['integer'], | 
					
						
							|  |  |  |             'name'                => ['string', 'min:1', 'max:255'], | 
					
						
							|  |  |  |             'description'         => ['string', 'max:1900'], | 
					
						
							|  |  |  |             'description_html'    => ['string', 'max:2000'], | 
					
						
							|  |  |  |             'tags'                => ['array'], | 
					
						
							|  |  |  |             'priority'            => ['integer'], | 
					
						
							|  |  |  |             'default_template_id' => ['nullable', 'integer'], | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         ], | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |     public function __construct( | 
					
						
							| 
									
										
										
										
											2024-02-08 00:37:36 +08:00
										 |  |  |         protected ChapterRepo $chapterRepo, | 
					
						
							|  |  |  |         protected ChapterQueries $queries, | 
					
						
							| 
									
										
										
										
											2024-02-11 23:42:37 +08:00
										 |  |  |         protected EntityQueries $entityQueries, | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a listing of chapters visible to the user. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function list() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-02-11 23:42:37 +08:00
										 |  |  |         $chapters = $this->queries->visibleForList() | 
					
						
							|  |  |  |             ->addSelect(['created_by', 'updated_by']); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         return $this->apiListingResponse($chapters, [ | 
					
						
							|  |  |  |             'id', 'book_id', 'name', 'slug', 'description', 'priority', | 
					
						
							| 
									
										
										
										
											2021-01-04 06:29:58 +08:00
										 |  |  |             'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by', | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Create a new chapter in the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function create(Request $request) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |         $requestData = $this->validate($request, $this->rules['create']); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $bookId = $request->get('book_id'); | 
					
						
							| 
									
										
										
										
											2024-02-11 23:42:37 +08:00
										 |  |  |         $book = $this->entityQueries->books->findVisibleByIdOrFail(intval($bookId)); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         $this->checkOwnablePermission('chapter-create', $book); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |         $chapter = $this->chapterRepo->create($requestData, $book); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  |         return response()->json($this->forJsonDisplay($chapter)); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * View the details of a single chapter. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function read(string $id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-02-08 00:37:36 +08:00
										 |  |  |         $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  |         $chapter = $this->forJsonDisplay($chapter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-11 23:42:37 +08:00
										 |  |  |         $chapter->load(['createdBy', 'updatedBy', 'ownedBy']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Note: More fields than usual here, for backwards compatibility,
 | 
					
						
							|  |  |  |         // due to previously accidentally including more fields that desired.
 | 
					
						
							|  |  |  |         $pages = $this->entityQueries->pages->visibleForChapterList($chapter->id) | 
					
						
							|  |  |  |             ->addSelect(['created_by', 'updated_by', 'revision_count', 'editor']) | 
					
						
							|  |  |  |             ->get(); | 
					
						
							|  |  |  |         $chapter->setRelation('pages', $pages); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         return response()->json($chapter); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Update the details of a single chapter. | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |      * Providing a 'book_id' property will essentially move the chapter | 
					
						
							|  |  |  |      * into that parent element if you have permissions to do so. | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function update(Request $request, string $id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |         $requestData = $this->validate($request, $this->rules()['update']); | 
					
						
							| 
									
										
										
										
											2024-02-08 00:37:36 +08:00
										 |  |  |         $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         $this->checkOwnablePermission('chapter-update', $chapter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |         if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) { | 
					
						
							|  |  |  |             $this->checkOwnablePermission('chapter-delete', $chapter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             try { | 
					
						
							|  |  |  |                 $this->chapterRepo->move($chapter, "book:{$requestData['book_id']}"); | 
					
						
							|  |  |  |             } catch (Exception $exception) { | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  |                 if ($exception instanceof PermissionsException) { | 
					
						
							| 
									
										
										
										
											2023-05-31 03:55:24 +08:00
										 |  |  |                     $this->showPermissionError(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $this->jsonError(trans('errors.selected_book_not_found')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $updatedChapter = $this->chapterRepo->update($chapter, $requestData); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  |         return response()->json($this->forJsonDisplay($updatedChapter)); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2020-11-28 23:21:54 +08:00
										 |  |  |      * Delete a chapter. | 
					
						
							|  |  |  |      * This will typically send the chapter to the recycle bin. | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function delete(string $id) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-02-08 00:37:36 +08:00
										 |  |  |         $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         $this->checkOwnablePermission('chapter-delete', $chapter); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->chapterRepo->destroy($chapter); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  |         return response('', 204); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected function forJsonDisplay(Chapter $chapter): Chapter | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $chapter = clone $chapter; | 
					
						
							|  |  |  |         $chapter->unsetRelations()->refresh(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $chapter->load(['tags']); | 
					
						
							| 
									
										
										
										
											2024-01-16 20:06:13 +08:00
										 |  |  |         $chapter->makeVisible('description_html'); | 
					
						
							|  |  |  |         $chapter->setAttribute('description_html', $chapter->descriptionHtml()); | 
					
						
							|  |  |  |         $chapter->setAttribute('book_slug', $chapter->book()->first()->slug); | 
					
						
							| 
									
										
										
										
											2023-12-21 21:23:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $chapter; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-23 07:28:41 +08:00
										 |  |  | } |