X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/be4f3d62cd37c7b83eb86bbf5fffa00d20acf2ec..refs/pull/2023/head:/app/Http/Controllers/PageController.php diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 80bbe56c1..b216c19a8 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -1,181 +1,144 @@ entityRepo = $entityRepo; - $this->exportService = $exportService; - $this->userRepo = $userRepo; + $this->pageRepo = $pageRepo; parent::__construct(); } /** * Show the form for creating a new page. - * @param string $bookSlug - * @param string $chapterSlug - * @return Response - * @internal param bool $pageSlug - * @throws NotFoundException + * @throws Throwable */ - public function create($bookSlug, $chapterSlug = null) + public function create(string $bookSlug, string $chapterSlug = null) { - if ($chapterSlug !== null) { - $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); - $book = $chapter->book; - } else { - $chapter = null; - $book = $this->entityRepo->getBySlug('book', $bookSlug); - } - - $parent = $chapter ? $chapter : $book; + $parent = $this->pageRepo->getParentFromSlugs($bookSlug, $chapterSlug); $this->checkOwnablePermission('page-create', $parent); // Redirect to draft edit screen if signed in - if ($this->signedIn) { - $draft = $this->entityRepo->getDraftPage($book, $chapter); + if ($this->isSignedIn()) { + $draft = $this->pageRepo->getNewDraftPage($parent); return redirect($draft->getUrl()); } // Otherwise show the edit view if they're a guest $this->setPageTitle(trans('entities.pages_new')); - return view('pages/guest-create', ['parent' => $parent]); + return view('pages.guest-create', ['parent' => $parent]); } /** * Create a new page as a guest user. - * @param Request $request - * @param string $bookSlug - * @param string|null $chapterSlug - * @return mixed - * @throws NotFoundException + * @throws ValidationException */ - public function createAsGuest(Request $request, $bookSlug, $chapterSlug = null) + public function createAsGuest(Request $request, string $bookSlug, string $chapterSlug = null) { $this->validate($request, [ 'name' => 'required|string|max:255' ]); - if ($chapterSlug !== null) { - $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); - $book = $chapter->book; - } else { - $chapter = null; - $book = $this->entityRepo->getBySlug('book', $bookSlug); - } - - $parent = $chapter ? $chapter : $book; + $parent = $this->pageRepo->getParentFromSlugs($bookSlug, $chapterSlug); $this->checkOwnablePermission('page-create', $parent); - $page = $this->entityRepo->getDraftPage($book, $chapter); - $this->entityRepo->publishPageDraft($page, [ + $page = $this->pageRepo->getNewDraftPage($parent); + $this->pageRepo->publishDraft($page, [ 'name' => $request->get('name'), 'html' => '' ]); + return redirect($page->getUrl('/edit')); } /** * Show form to continue editing a draft page. - * @param string $bookSlug - * @param int $pageId - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws NotFoundException */ - public function editDraft($bookSlug, $pageId) + public function editDraft(string $bookSlug, int $pageId) { - $draft = $this->entityRepo->getById('page', $pageId, true); - $this->checkOwnablePermission('page-create', $draft->parent); + $draft = $this->pageRepo->getById($pageId); + $this->checkOwnablePermission('page-create', $draft->parent()); $this->setPageTitle(trans('entities.pages_edit_draft')); - $draftsEnabled = $this->signedIn; - return view('pages/edit', [ + $draftsEnabled = $this->isSignedIn(); + $templates = $this->pageRepo->getTemplates(10); + + return view('pages.edit', [ 'page' => $draft, 'book' => $draft->book, 'isDraft' => true, - 'draftsEnabled' => $draftsEnabled + 'draftsEnabled' => $draftsEnabled, + 'templates' => $templates, ]); } /** * Store a new page by changing a draft into a page. - * @param Request $request - * @param string $bookSlug - * @param int $pageId - * @return Response + * @throws NotFoundException + * @throws ValidationException */ - public function store(Request $request, $bookSlug, $pageId) + public function store(Request $request, string $bookSlug, int $pageId) { $this->validate($request, [ 'name' => 'required|string|max:255' ]); + $draftPage = $this->pageRepo->getById($pageId); + $this->checkOwnablePermission('page-create', $draftPage->parent()); - $input = $request->all(); - $draftPage = $this->entityRepo->getById('page', $pageId, true); - $book = $draftPage->book; + $page = $this->pageRepo->publishDraft($draftPage, $request->all()); + Activity::add($page, 'page_create', $draftPage->book->id); - $parent = $draftPage->parent; - $this->checkOwnablePermission('page-create', $parent); - - if ($parent->isA('chapter')) { - $input['priority'] = $this->entityRepo->getNewChapterPriority($parent); - } else { - $input['priority'] = $this->entityRepo->getNewBookPriority($parent); - } - - $page = $this->entityRepo->publishPageDraft($draftPage, $input); - - Activity::add($page, 'page_create', $book->id); return redirect($page->getUrl()); } /** * Display the specified page. * If the page is not found via the slug the revisions are searched for a match. - * @param string $bookSlug - * @param string $pageSlug - * @return Response * @throws NotFoundException */ - public function show($bookSlug, $pageSlug) + public function show(string $bookSlug, string $pageSlug) { try { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); } catch (NotFoundException $e) { - $page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug); + $page = $this->pageRepo->getByOldSlug($bookSlug, $pageSlug); + if ($page === null) { throw $e; } + return redirect($page->getUrl()); } $this->checkOwnablePermission('page-view', $page); - $page->html = $this->entityRepo->renderPage($page); - $sidebarTree = $this->entityRepo->getBookChildren($page->book); - $pageNav = $this->entityRepo->getPageNav($page->html); + $pageContent = (new PageContent($page)); + $page->html = $pageContent->render(); + $sidebarTree = (new BookContents($page->book))->getTree(); + $pageNav = $pageContent->getNavigation($page->html); - // check if the comment's are enabled + // Check if page comments are enabled $commentsEnabled = !setting('app-disable-comments'); if ($commentsEnabled) { $page->load(['comments.createdBy']); @@ -183,8 +146,9 @@ class PageController extends Controller Views::add($page); $this->setPageTitle($page->getShortName()); - return view('pages/show', [ - 'page' => $page,'book' => $page->book, + return view('pages.show', [ + 'page' => $page, + 'book' => $page->book, 'current' => $page, 'sidebarTree' => $sidebarTree, 'commentsEnabled' => $commentsEnabled, @@ -194,95 +158,89 @@ class PageController extends Controller /** * Get page from an ajax request. - * @param int $pageId - * @return \Illuminate\Http\JsonResponse + * @throws NotFoundException */ - public function getPageAjax($pageId) + public function getPageAjax(int $pageId) { - $page = $this->entityRepo->getById('page', $pageId); + $page = $this->pageRepo->getById($pageId); return response()->json($page); } /** * Show the form for editing the specified page. - * @param string $bookSlug - * @param string $pageSlug - * @return Response + * @throws NotFoundException */ - public function edit($bookSlug, $pageSlug) + public function edit(string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - $this->setPageTitle(trans('entities.pages_editing_named', ['pageName'=>$page->getShortName()])); + $page->isDraft = false; + $editActivity = new PageEditActivity($page); // Check for active editing $warnings = []; - if ($this->entityRepo->isPageEditingActive($page, 60)) { - $warnings[] = $this->entityRepo->getPageEditingActiveMessage($page, 60); + if ($editActivity->hasActiveEditing()) { + $warnings[] = $editActivity->activeEditingMessage(); } // Check for a current draft version for this user - if ($this->entityRepo->hasUserGotPageDraft($page, $this->currentUser->id)) { - $draft = $this->entityRepo->getUserPageDraft($page, $this->currentUser->id); - $page->name = $draft->name; - $page->html = $draft->html; - $page->markdown = $draft->markdown; + $userDraft = $this->pageRepo->getUserDraft($page); + if ($userDraft !== null) { + $page->forceFill($userDraft->only(['name', 'html', 'markdown'])); $page->isDraft = true; - $warnings [] = $this->entityRepo->getUserPageDraftMessage($draft); + $warnings[] = $editActivity->getEditingActiveDraftMessage($userDraft); } if (count($warnings) > 0) { - session()->flash('warning', implode("\n", $warnings)); + $this->showWarningNotification(implode("\n", $warnings)); } - $draftsEnabled = $this->signedIn; - return view('pages/edit', [ + $templates = $this->pageRepo->getTemplates(10); + $draftsEnabled = $this->isSignedIn(); + $this->setPageTitle(trans('entities.pages_editing_named', ['pageName' => $page->getShortName()])); + return view('pages.edit', [ 'page' => $page, 'book' => $page->book, 'current' => $page, - 'draftsEnabled' => $draftsEnabled + 'draftsEnabled' => $draftsEnabled, + 'templates' => $templates, ]); } /** * Update the specified page in storage. - * @param Request $request - * @param string $bookSlug - * @param string $pageSlug - * @return Response + * @throws ValidationException + * @throws NotFoundException */ - public function update(Request $request, $bookSlug, $pageSlug) + public function update(Request $request, string $bookSlug, string $pageSlug) { $this->validate($request, [ 'name' => 'required|string|max:255' ]); - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - $this->entityRepo->updatePage($page, $page->book->id, $request->all()); + + $this->pageRepo->update($page, $request->all()); Activity::add($page, 'page_update', $page->book->id); + return redirect($page->getUrl()); } /** * Save a draft update as a revision. - * @param Request $request - * @param int $pageId - * @return \Illuminate\Http\JsonResponse + * @throws NotFoundException */ - public function saveDraft(Request $request, $pageId) + public function saveDraft(Request $request, int $pageId) { - $page = $this->entityRepo->getById('page', $pageId, true); + $page = $this->pageRepo->getById($pageId); $this->checkOwnablePermission('page-update', $page); - if (!$this->signedIn) { - return response()->json([ - 'status' => 'error', - 'message' => trans('errors.guests_cannot_save_drafts'), - ], 500); + if (!$this->isSignedIn()) { + return $this->jsonError(trans('errors.guests_cannot_save_drafts'), 500); } - $draft = $this->entityRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown'])); + $draft = $this->pageRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown'])); $updateTime = $draft->updated_at->timestamp; return response()->json([ @@ -293,413 +251,226 @@ class PageController extends Controller } /** - * Redirect from a special link url which - * uses the page id rather than the name. - * @param int $pageId - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * Redirect from a special link url which uses the page id rather than the name. + * @throws NotFoundException */ - public function redirectFromLink($pageId) + public function redirectFromLink(int $pageId) { - $page = $this->entityRepo->getById('page', $pageId); + $page = $this->pageRepo->getById($pageId); return redirect($page->getUrl()); } /** * Show the deletion page for the specified page. - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\View\View + * @throws NotFoundException */ - public function showDelete($bookSlug, $pageSlug) + public function showDelete(string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-delete', $page); $this->setPageTitle(trans('entities.pages_delete_named', ['pageName'=>$page->getShortName()])); - return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]); + return view('pages.delete', [ + 'book' => $page->book, + 'page' => $page, + 'current' => $page + ]); } - /** * Show the deletion page for the specified page. - * @param string $bookSlug - * @param int $pageId - * @return \Illuminate\View\View * @throws NotFoundException */ - public function showDeleteDraft($bookSlug, $pageId) + public function showDeleteDraft(string $bookSlug, int $pageId) { - $page = $this->entityRepo->getById('page', $pageId, true); + $page = $this->pageRepo->getById($pageId); $this->checkOwnablePermission('page-update', $page); $this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName'=>$page->getShortName()])); - return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]); + return view('pages.delete', [ + 'book' => $page->book, + 'page' => $page, + 'current' => $page + ]); } /** * Remove the specified page from storage. - * @param string $bookSlug - * @param string $pageSlug - * @return Response - * @internal param int $id + * @throws NotFoundException + * @throws Throwable + * @throws NotifyException */ - public function destroy($bookSlug, $pageSlug) + public function destroy(string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $book = $page->book; + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-delete', $page); - $this->entityRepo->destroyPage($page); - Activity::addMessage('page_delete', $book->id, $page->name); - session()->flash('success', trans('entities.pages_delete_success')); - return redirect($book->getUrl()); + $book = $page->book; + $parent = $page->chapter ?? $book; + $this->pageRepo->destroy($page); + Activity::addMessage('page_delete', $page->name, $book->id); + + $this->showSuccessNotification(trans('entities.pages_delete_success')); + return redirect($parent->getUrl()); } /** * Remove the specified draft page from storage. - * @param string $bookSlug - * @param int $pageId - * @return Response * @throws NotFoundException + * @throws NotifyException + * @throws Throwable */ - public function destroyDraft($bookSlug, $pageId) + public function destroyDraft(string $bookSlug, int $pageId) { - $page = $this->entityRepo->getById('page', $pageId, true); + $page = $this->pageRepo->getById($pageId); $book = $page->book; + $chapter = $page->chapter; $this->checkOwnablePermission('page-update', $page); - session()->flash('success', trans('entities.pages_delete_draft_success')); - $this->entityRepo->destroyPage($page); - return redirect($book->getUrl()); - } - - /** - * Shows the last revisions for this page. - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\View\View - */ - public function showRevisions($bookSlug, $pageSlug) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()])); - return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]); - } - - /** - * Shows a preview of a single revision - * @param string $bookSlug - * @param string $pageSlug - * @param int $revisionId - * @return \Illuminate\View\View - */ - public function showRevision($bookSlug, $pageSlug, $revisionId) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $revision = $page->revisions()->where('id', '=', $revisionId)->first(); - if ($revision === null) { - abort(404); - } - - $page->fill($revision->toArray()); - $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()])); - - return view('pages/revision', [ - 'page' => $page, - 'book' => $page->book, - 'revision' => $revision - ]); - } - - /** - * Shows the changes of a single revision - * @param string $bookSlug - * @param string $pageSlug - * @param int $revisionId - * @return \Illuminate\View\View - */ - public function showRevisionChanges($bookSlug, $pageSlug, $revisionId) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $revision = $page->revisions()->where('id', '=', $revisionId)->first(); - if ($revision === null) { - abort(404); - } - - $prev = $revision->getPrevious(); - $prevContent = ($prev === null) ? '' : $prev->html; - $diff = (new Htmldiff)->diff($prevContent, $revision->html); - - $page->fill($revision->toArray()); - $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()])); - - return view('pages/revision', [ - 'page' => $page, - 'book' => $page->book, - 'diff' => $diff, - 'revision' => $revision - ]); - } - - /** - * Restores a page using the content of the specified revision. - * @param string $bookSlug - * @param string $pageSlug - * @param int $revisionId - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector - */ - public function restoreRevision($bookSlug, $pageSlug, $revisionId) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->checkOwnablePermission('page-update', $page); - $page = $this->entityRepo->restorePageRevision($page, $page->book, $revisionId); - Activity::add($page, 'page_restore', $page->book->id); - return redirect($page->getUrl()); - } - - - /** - * Deletes a revision using the id of the specified revision. - * @param string $bookSlug - * @param string $pageSlug - * @param int $revId - * @throws NotFoundException - * @throws BadRequestException - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector - */ - public function destroyRevision($bookSlug, $pageSlug, $revId) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->checkOwnablePermission('page-delete', $page); - $revision = $page->revisions()->where('id', '=', $revId)->first(); - if ($revision === null) { - throw new NotFoundException("Revision #{$revId} not found"); - } + $this->pageRepo->destroy($page); - // Get the current revision for the page - $currentRevision = $page->getCurrentRevision(); + $this->showSuccessNotification(trans('entities.pages_delete_draft_success')); - // Check if its the latest revision, cannot delete latest revision. - if (intval($currentRevision->id) === intval($revId)) { - session()->flash('error', trans('entities.revision_cannot_delete_latest')); - return response()->view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page], 400); + if ($chapter && userCan('view', $chapter)) { + return redirect($chapter->getUrl()); } - - $revision->delete(); - session()->flash('success', trans('entities.revision_delete_success')); - return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]); - } - - /** - * Exports a page to a PDF. - * https://github.com/barryvdh/laravel-dompdf - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\Http\Response - */ - public function exportPdf($bookSlug, $pageSlug) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $page->html = $this->entityRepo->renderPage($page); - $pdfContent = $this->exportService->pageToPdf($page); - return $this->downloadResponse($pdfContent, $pageSlug . '.pdf'); - } - - /** - * Export a page to a self-contained HTML file. - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\Http\Response - */ - public function exportHtml($bookSlug, $pageSlug) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $page->html = $this->entityRepo->renderPage($page); - $containedHtml = $this->exportService->pageToContainedHtml($page); - return $this->downloadResponse($containedHtml, $pageSlug . '.html'); - } - - /** - * Export a page to a simple plaintext .txt file. - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\Http\Response - */ - public function exportPlainText($bookSlug, $pageSlug) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $pageText = $this->exportService->pageToPlainText($page); - return $this->downloadResponse($pageText, $pageSlug . '.txt'); - } - - /** - * Show a listing of recently created pages - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - */ - public function showRecentlyCreated() - { - $pages = $this->entityRepo->getRecentlyCreatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-created')); - return view('pages/detailed-listing', [ - 'title' => trans('entities.recently_created_pages'), - 'pages' => $pages - ]); + return redirect($book->getUrl()); } /** - * Show a listing of recently created pages - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * Show a listing of recently created pages. */ public function showRecentlyUpdated() { - $pages = $this->entityRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated')); - return view('pages/detailed-listing', [ + $pages = Page::visible()->orderBy('updated_at', 'desc') + ->paginate(20) + ->setPath(url('/pages/recently-updated')); + + return view('pages.detailed-listing', [ 'title' => trans('entities.recently_updated_pages'), 'pages' => $pages ]); } - /** - * Show the Restrictions view. - * @param string $bookSlug - * @param string $pageSlug - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - */ - public function showRestrict($bookSlug, $pageSlug) - { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->checkOwnablePermission('restrictions-manage', $page); - $roles = $this->userRepo->getRestrictableRoles(); - return view('pages/restrictions', [ - 'page' => $page, - 'roles' => $roles - ]); - } - /** * Show the view to choose a new parent to move a page into. - * @param string $bookSlug - * @param string $pageSlug - * @return mixed * @throws NotFoundException */ - public function showMove($bookSlug, $pageSlug) + public function showMove(string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); - return view('pages/move', [ + $this->checkOwnablePermission('page-delete', $page); + return view('pages.move', [ 'book' => $page->book, 'page' => $page ]); } /** - * Does the action of moving the location of a page - * @param string $bookSlug - * @param string $pageSlug - * @param Request $request - * @return mixed + * Does the action of moving the location of a page. * @throws NotFoundException + * @throws Throwable */ - public function move($bookSlug, $pageSlug, Request $request) + public function move(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-update', $page); + $this->checkOwnablePermission('page-delete', $page); $entitySelection = $request->get('entity_selection', null); if ($entitySelection === null || $entitySelection === '') { return redirect($page->getUrl()); } - $stringExploded = explode(':', $entitySelection); - $entityType = $stringExploded[0]; - $entityId = intval($stringExploded[1]); - - try { - $parent = $this->entityRepo->getById($entityType, $entityId); - } catch (\Exception $e) { - session()->flash(trans('entities.selected_book_chapter_not_found')); + $parent = $this->pageRepo->move($page, $entitySelection); + } catch (Exception $exception) { + if ($exception instanceof PermissionsException) { + $this->showPermissionError(); + } + + $this->showErrorNotification(trans('errors.selected_book_chapter_not_found')); return redirect()->back(); } - $this->checkOwnablePermission('page-create', $parent); - - $this->entityRepo->changePageParent($page, $parent); Activity::add($page, 'page_move', $page->book->id); - session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name])); - + $this->showSuccessNotification(trans('entities.pages_move_success', ['parentName' => $parent->name])); return redirect($page->getUrl()); } /** * Show the view to copy a page. - * @param string $bookSlug - * @param string $pageSlug - * @return mixed * @throws NotFoundException */ - public function showCopy($bookSlug, $pageSlug) + public function showCopy(string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->checkOwnablePermission('page-update', $page); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); + $this->checkOwnablePermission('page-view', $page); session()->flashInput(['name' => $page->name]); - return view('pages/copy', [ + return view('pages.copy', [ 'book' => $page->book, 'page' => $page ]); } + /** * Create a copy of a page within the requested target destination. - * @param string $bookSlug - * @param string $pageSlug - * @param Request $request - * @return mixed * @throws NotFoundException + * @throws Throwable */ - public function copy($bookSlug, $pageSlug, Request $request) + public function copy(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); - $this->checkOwnablePermission('page-update', $page); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); + $this->checkOwnablePermission('page-view', $page); - $entitySelection = $request->get('entity_selection', null); - if ($entitySelection === null || $entitySelection === '') { - $parent = $page->chapter ? $page->chapter : $page->book; - } else { - $stringExploded = explode(':', $entitySelection); - $entityType = $stringExploded[0]; - $entityId = intval($stringExploded[1]); - - try { - $parent = $this->entityRepo->getById($entityType, $entityId); - } catch (\Exception $e) { - session()->flash(trans('entities.selected_book_chapter_not_found')); - return redirect()->back(); - } - } + $entitySelection = $request->get('entity_selection', null) ?? null; + $newName = $request->get('name', null); - $this->checkOwnablePermission('page-create', $parent); + try { + $pageCopy = $this->pageRepo->copy($page, $entitySelection, $newName); + } catch (Exception $exception) { + if ($exception instanceof PermissionsException) { + $this->showPermissionError(); + } - $pageCopy = $this->entityRepo->copyPage($page, $parent, $request->get('name', '')); + $this->showErrorNotification(trans('errors.selected_book_chapter_not_found')); + return redirect()->back(); + } Activity::add($pageCopy, 'page_create', $pageCopy->book->id); - session()->flash('success', trans('entities.pages_copy_success')); + $this->showSuccessNotification(trans('entities.pages_copy_success')); return redirect($pageCopy->getUrl()); } + /** + * Show the Permissions view. + * @throws NotFoundException + */ + public function showPermissions(string $bookSlug, string $pageSlug) + { + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); + $this->checkOwnablePermission('restrictions-manage', $page); + return view('pages.permissions', [ + 'page' => $page, + ]); + } + /** * Set the permissions for this page. - * @param string $bookSlug - * @param string $pageSlug - * @param Request $request - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector * @throws NotFoundException + * @throws Throwable */ - public function restrict($bookSlug, $pageSlug, Request $request) + public function permissions(Request $request, string $bookSlug, string $pageSlug) { - $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); + $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('restrictions-manage', $page); - $this->entityRepo->updateEntityPermissionsFromRequest($request, $page); - session()->flash('success', trans('entities.pages_permissions_success')); + + $restricted = $request->get('restricted') === 'true'; + $permissions = $request->filled('restrictions') ? collect($request->get('restrictions')) : null; + $this->pageRepo->updatePermissions($page, $restricted, $permissions); + + $this->showSuccessNotification(trans('entities.pages_permissions_success')); return redirect($page->getUrl()); } }