Extracted page copy to new cloner class

Fundemental refactor for planned additional clone operations.
No behaviour change intended in this commit.
This commit is contained in:
Dan Brown 2021-12-19 12:56:27 +00:00
parent da01913616
commit 3f9527f166
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9
3 changed files with 54 additions and 49 deletions

View file

@ -346,43 +346,6 @@ class PageRepo
return $parent; 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: * Find a page parent entity via a identifier string in the format:
* {type}:{id} * {type}:{id}
@ -390,7 +353,7 @@ class PageRepo
* *
* @throws MoveOperationException * @throws MoveOperationException
*/ */
protected function findParentByIdentifier(string $identifier): ?Entity public function findParentByIdentifier(string $identifier): ?Entity
{ {
$stringExploded = explode(':', $identifier); $stringExploded = explode(':', $identifier);
$entityType = $stringExploded[0]; $entityType = $stringExploded[0];

View file

@ -0,0 +1,44 @@
<?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);
}
}

View file

@ -6,6 +6,7 @@ use BookStack\Actions\View;
use BookStack\Entities\Models\Page; use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Repos\PageRepo;
use BookStack\Entities\Tools\BookContents; use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\Cloner;
use BookStack\Entities\Tools\NextPreviousContentLocator; use BookStack\Entities\Tools\NextPreviousContentLocator;
use BookStack\Entities\Tools\PageContent; use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditActivity; use BookStack\Entities\Tools\PageEditActivity;
@ -447,26 +448,23 @@ class PageController extends Controller
* @throws NotFoundException * @throws NotFoundException
* @throws Throwable * @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); $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
$this->checkOwnablePermission('page-view', $page); $this->checkOwnablePermission('page-view', $page);
$entitySelection = $request->get('entity_selection', null) ?? null; $entitySelection = $request->get('entity_selection') ?: null;
$newName = $request->get('name', null); $newParent = $entitySelection ? $this->pageRepo->findParentByIdentifier($entitySelection) : $page->getParent();
try {
$pageCopy = $this->pageRepo->copy($page, $entitySelection, $newName);
} catch (Exception $exception) {
if ($exception instanceof PermissionsException) {
$this->showPermissionError();
}
if (is_null($newParent)) {
$this->showErrorNotification(trans('errors.selected_book_chapter_not_found')); $this->showErrorNotification(trans('errors.selected_book_chapter_not_found'));
return redirect()->back(); 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')); $this->showSuccessNotification(trans('entities.pages_copy_success'));
return redirect($pageCopy->getUrl()); return redirect($pageCopy->getUrl());