Fundemental refactor for planned additional clone operations.
No behaviour change intended in this commit.
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}
*
* @throws MoveOperationException
*/
- protected function findParentByIdentifier(string $identifier): ?Entity
+ public function findParentByIdentifier(string $identifier): ?Entity
{
$stringExploded = explode(':', $identifier);
$entityType = $stringExploded[0];
--- /dev/null
+<?php
+
+namespace BookStack\Entities\Tools;
+
+use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Models\Page;
+use BookStack\Entities\Repos\PageRepo;
+
+class Cloner
+{
+
+ /**
+ * @var PageRepo
+ */
+ protected $pageRepo;
+
+ public function __construct(PageRepo $pageRepo)
+ {
+ $this->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
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;
* @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());