X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/c429cf78187e80deb63982a282a1c6889f30291a..refs/pull/4191/head:/app/Http/Controllers/ChapterController.php diff --git a/app/Http/Controllers/ChapterController.php b/app/Http/Controllers/ChapterController.php index b27fb4f77..4d2bcb2f1 100644 --- a/app/Http/Controllers/ChapterController.php +++ b/app/Http/Controllers/ChapterController.php @@ -6,24 +6,26 @@ use BookStack\Actions\View; use BookStack\Entities\Models\Book; use BookStack\Entities\Repos\ChapterRepo; use BookStack\Entities\Tools\BookContents; +use BookStack\Entities\Tools\Cloner; +use BookStack\Entities\Tools\HierarchyTransformer; use BookStack\Entities\Tools\NextPreviousContentLocator; -use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Exceptions\MoveOperationException; use BookStack\Exceptions\NotFoundException; +use BookStack\Exceptions\PermissionsException; +use BookStack\References\ReferenceFetcher; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Throwable; class ChapterController extends Controller { - protected $chapterRepo; + protected ChapterRepo $chapterRepo; + protected ReferenceFetcher $referenceFetcher; - /** - * ChapterController constructor. - */ - public function __construct(ChapterRepo $chapterRepo) + public function __construct(ChapterRepo $chapterRepo, ReferenceFetcher $referenceFetcher) { $this->chapterRepo = $chapterRepo; + $this->referenceFetcher = $referenceFetcher; } /** @@ -47,7 +49,7 @@ class ChapterController extends Controller public function store(Request $request, string $bookSlug) { $this->validate($request, [ - 'name' => 'required|string|max:255', + 'name' => ['required', 'string', 'max:255'], ]); $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail(); @@ -74,13 +76,14 @@ class ChapterController extends Controller $this->setPageTitle($chapter->getShortName()); return view('chapters.show', [ - 'book' => $chapter->book, - 'chapter' => $chapter, - 'current' => $chapter, - 'sidebarTree' => $sidebarTree, - 'pages' => $pages, - 'next' => $nextPreviousLocator->getNext(), - 'previous' => $nextPreviousLocator->getPrevious(), + 'book' => $chapter->book, + 'chapter' => $chapter, + 'current' => $chapter, + 'sidebarTree' => $sidebarTree, + 'pages' => $pages, + 'next' => $nextPreviousLocator->getNext(), + 'previous' => $nextPreviousLocator->getPrevious(), + 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($chapter), ]); } @@ -179,6 +182,8 @@ class ChapterController extends Controller try { $newBook = $this->chapterRepo->move($chapter, $entitySelection); + } catch (PermissionsException $exception) { + $this->showPermissionError(); } catch (MoveOperationException $exception) { $this->showErrorNotification(trans('errors.selected_book_not_found')); @@ -191,34 +196,64 @@ class ChapterController extends Controller } /** - * Show the Restrictions view. + * Show the view to copy a chapter. * * @throws NotFoundException */ - public function showPermissions(string $bookSlug, string $chapterSlug) + public function showCopy(string $bookSlug, string $chapterSlug) { $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug); - $this->checkOwnablePermission('restrictions-manage', $chapter); + $this->checkOwnablePermission('chapter-view', $chapter); - return view('chapters.permissions', [ + session()->flashInput(['name' => $chapter->name]); + + return view('chapters.copy', [ + 'book' => $chapter->book, 'chapter' => $chapter, ]); } /** - * Set the restrictions for this chapter. + * Create a copy of a chapter within the requested target destination. * * @throws NotFoundException + * @throws Throwable */ - public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug, string $chapterSlug) + public function copy(Request $request, Cloner $cloner, string $bookSlug, string $chapterSlug) { $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug); - $this->checkOwnablePermission('restrictions-manage', $chapter); + $this->checkOwnablePermission('chapter-view', $chapter); - $permissionsUpdater->updateFromPermissionsForm($chapter, $request); + $entitySelection = $request->get('entity_selection') ?: null; + $newParentBook = $entitySelection ? $this->chapterRepo->findParentByIdentifier($entitySelection) : $chapter->getParent(); - $this->showSuccessNotification(trans('entities.chapters_permissions_success')); + if (is_null($newParentBook)) { + $this->showErrorNotification(trans('errors.selected_book_not_found')); - return redirect($chapter->getUrl()); + return redirect()->back(); + } + + $this->checkOwnablePermission('chapter-create', $newParentBook); + + $newName = $request->get('name') ?: $chapter->name; + $chapterCopy = $cloner->cloneChapter($chapter, $newParentBook, $newName); + $this->showSuccessNotification(trans('entities.chapters_copy_success')); + + return redirect($chapterCopy->getUrl()); + } + + /** + * Convert the chapter to a book. + */ + public function convertToBook(HierarchyTransformer $transformer, string $bookSlug, string $chapterSlug) + { + $chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug); + $this->checkOwnablePermission('chapter-update', $chapter); + $this->checkOwnablePermission('chapter-delete', $chapter); + $this->checkPermission('book-create-all'); + + $book = $transformer->transformChapterToBook($chapter); + + return redirect($book->getUrl()); } }