diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index b315bead9..b914632b5 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -346,43 +346,6 @@ class PageRepo return $parent; } - /** - * Copy an existing page in the system. - * Optionally providing a new parent via string identifier and a new name. - * - * @throws MoveOperationException - * @throws PermissionsException - */ - public function copy(Page $page, string $parentIdentifier = null, string $newName = null): Page - { - $parent = $parentIdentifier ? $this->findParentByIdentifier($parentIdentifier) : $page->getParent(); - if ($parent === null) { - throw new MoveOperationException('Book or chapter to move page into not found'); - } - - if (!userCan('page-create', $parent)) { - throw new PermissionsException('User does not have permission to create a page within the new parent'); - } - - $copyPage = $this->getNewDraftPage($parent); - $pageData = $page->getAttributes(); - - // Update name - if (!empty($newName)) { - $pageData['name'] = $newName; - } - - // Copy tags from previous page if set - if ($page->tags) { - $pageData['tags'] = []; - foreach ($page->tags as $tag) { - $pageData['tags'][] = ['name' => $tag->name, 'value' => $tag->value]; - } - } - - return $this->publishDraft($copyPage, $pageData); - } - /** * Find a page parent entity via a identifier string in the format: * {type}:{id} @@ -390,7 +353,7 @@ class PageRepo * * @throws MoveOperationException */ - protected function findParentByIdentifier(string $identifier): ?Entity + public function findParentByIdentifier(string $identifier): ?Entity { $stringExploded = explode(':', $identifier); $entityType = $stringExploded[0]; diff --git a/app/Entities/Tools/Cloner.php b/app/Entities/Tools/Cloner.php new file mode 100644 index 000000000..3ce4dff20 --- /dev/null +++ b/app/Entities/Tools/Cloner.php @@ -0,0 +1,44 @@ +pageRepo = $pageRepo; + } + + /** + * Clone the given page into the given parent using the provided name. + */ + public function clonePage(Page $original, Entity $parent, string $newName): Page + { + $copyPage = $this->pageRepo->getNewDraftPage($parent); + $pageData = $original->getAttributes(); + + // Update name + $pageData['name'] = $newName; + + // Copy tags from previous page if set + if ($original->tags) { + $pageData['tags'] = []; + foreach ($original->tags as $tag) { + $pageData['tags'][] = ['name' => $tag->name, 'value' => $tag->value]; + } + } + + return $this->pageRepo->publishDraft($copyPage, $pageData); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 7d5d93ffa..4a01dcc62 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -6,6 +6,7 @@ use BookStack\Actions\View; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Tools\BookContents; +use BookStack\Entities\Tools\Cloner; use BookStack\Entities\Tools\NextPreviousContentLocator; use BookStack\Entities\Tools\PageContent; use BookStack\Entities\Tools\PageEditActivity; @@ -447,26 +448,23 @@ class PageController extends Controller * @throws NotFoundException * @throws Throwable */ - public function copy(Request $request, string $bookSlug, string $pageSlug) + public function copy(Request $request, Cloner $cloner, string $bookSlug, string $pageSlug) { $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $this->checkOwnablePermission('page-view', $page); - $entitySelection = $request->get('entity_selection', null) ?? null; - $newName = $request->get('name', null); - - try { - $pageCopy = $this->pageRepo->copy($page, $entitySelection, $newName); - } catch (Exception $exception) { - if ($exception instanceof PermissionsException) { - $this->showPermissionError(); - } + $entitySelection = $request->get('entity_selection') ?: null; + $newParent = $entitySelection ? $this->pageRepo->findParentByIdentifier($entitySelection) : $page->getParent(); + if (is_null($newParent)) { $this->showErrorNotification(trans('errors.selected_book_chapter_not_found')); - return redirect()->back(); } + $this->checkOwnablePermission('page-create', $newParent); + + $newName = $request->get('name') ?: $page->name; + $pageCopy = $cloner->clonePage($page, $newParent, $newName); $this->showSuccessNotification(trans('entities.pages_copy_success')); return redirect($pageCopy->getUrl());