X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/968bc8cdf354d9cbe29b88abdc747a7845031fab..HEAD:/app/Entities/Controllers/ChapterApiController.php diff --git a/app/Entities/Controllers/ChapterApiController.php b/app/Entities/Controllers/ChapterApiController.php index 7f01e445a..430654330 100644 --- a/app/Entities/Controllers/ChapterApiController.php +++ b/app/Entities/Controllers/ChapterApiController.php @@ -2,8 +2,9 @@ namespace BookStack\Entities\Controllers; -use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Chapter; +use BookStack\Entities\Queries\ChapterQueries; +use BookStack\Entities\Queries\EntityQueries; use BookStack\Entities\Repos\ChapterRepo; use BookStack\Exceptions\PermissionsException; use BookStack\Http\ApiController; @@ -15,23 +16,29 @@ class ChapterApiController extends ApiController { protected $rules = [ 'create' => [ - 'book_id' => ['required', 'integer'], - 'name' => ['required', 'string', 'max:255'], - 'description' => ['string', 'max:1000'], - 'tags' => ['array'], - 'priority' => ['integer'], + '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'], ], 'update' => [ - 'book_id' => ['integer'], - 'name' => ['string', 'min:1', 'max:255'], - 'description' => ['string', 'max:1000'], - 'tags' => ['array'], - 'priority' => ['integer'], + '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'], ], ]; public function __construct( - protected ChapterRepo $chapterRepo + protected ChapterRepo $chapterRepo, + protected ChapterQueries $queries, + protected EntityQueries $entityQueries, ) { } @@ -40,7 +47,8 @@ class ChapterApiController extends ApiController */ public function list() { - $chapters = Chapter::visible(); + $chapters = $this->queries->visibleForList() + ->addSelect(['created_by', 'updated_by']); return $this->apiListingResponse($chapters, [ 'id', 'book_id', 'name', 'slug', 'description', 'priority', @@ -56,12 +64,12 @@ class ChapterApiController extends ApiController $requestData = $this->validate($request, $this->rules['create']); $bookId = $request->get('book_id'); - $book = Book::visible()->findOrFail($bookId); + $book = $this->entityQueries->books->findVisibleByIdOrFail(intval($bookId)); $this->checkOwnablePermission('chapter-create', $book); $chapter = $this->chapterRepo->create($requestData, $book); - return response()->json($chapter->load(['tags'])); + return response()->json($this->forJsonDisplay($chapter)); } /** @@ -69,9 +77,17 @@ class ChapterApiController extends ApiController */ public function read(string $id) { - $chapter = Chapter::visible()->with(['tags', 'createdBy', 'updatedBy', 'ownedBy', 'pages' => function (HasMany $query) { - $query->scopes('visible')->get(['id', 'name', 'slug']); - }])->findOrFail($id); + $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); + $chapter = $this->forJsonDisplay($chapter); + + $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); return response()->json($chapter); } @@ -84,7 +100,7 @@ class ChapterApiController extends ApiController public function update(Request $request, string $id) { $requestData = $this->validate($request, $this->rules()['update']); - $chapter = Chapter::visible()->findOrFail($id); + $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); $this->checkOwnablePermission('chapter-update', $chapter); if ($request->has('book_id') && $chapter->book_id !== intval($requestData['book_id'])) { @@ -93,7 +109,7 @@ class ChapterApiController extends ApiController try { $this->chapterRepo->move($chapter, "book:{$requestData['book_id']}"); } catch (Exception $exception) { - if ($exception instanceof PermissionsException) { + if ($exception instanceof PermissionsException) { $this->showPermissionError(); } @@ -103,7 +119,7 @@ class ChapterApiController extends ApiController $updatedChapter = $this->chapterRepo->update($chapter, $requestData); - return response()->json($updatedChapter->load(['tags'])); + return response()->json($this->forJsonDisplay($updatedChapter)); } /** @@ -112,11 +128,24 @@ class ChapterApiController extends ApiController */ public function delete(string $id) { - $chapter = Chapter::visible()->findOrFail($id); + $chapter = $this->queries->findVisibleByIdOrFail(intval($id)); $this->checkOwnablePermission('chapter-delete', $chapter); $this->chapterRepo->destroy($chapter); return response('', 204); } + + protected function forJsonDisplay(Chapter $chapter): Chapter + { + $chapter = clone $chapter; + $chapter->unsetRelations()->refresh(); + + $chapter->load(['tags']); + $chapter->makeVisible('description_html'); + $chapter->setAttribute('description_html', $chapter->descriptionHtml()); + $chapter->setAttribute('book_slug', $chapter->book()->first()->slug); + + return $chapter; + } }