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:
parent
da01913616
commit
3f9527f166
3 changed files with 54 additions and 49 deletions
|
@ -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];
|
||||||
|
|
44
app/Entities/Tools/Cloner.php
Normal file
44
app/Entities/Tools/Cloner.php
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in a new issue