1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-12-13 07:42:23 +03:00

Copying: Added reference change context tracking

Added core wiring in the cloning logic, just need to implement core
logic in the updater now.
This commit is contained in:
Dan Brown
2025-11-25 14:46:36 +00:00
parent ba675b6349
commit 674bb84fac
3 changed files with 67 additions and 1 deletions

View File

@@ -13,30 +13,47 @@ use BookStack\Entities\Repos\BookRepo;
use BookStack\Entities\Repos\ChapterRepo; use BookStack\Entities\Repos\ChapterRepo;
use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Repos\PageRepo;
use BookStack\Permissions\Permission; use BookStack\Permissions\Permission;
use BookStack\References\ReferenceChangeContext;
use BookStack\References\ReferenceUpdater;
use BookStack\Uploads\Image; use BookStack\Uploads\Image;
use BookStack\Uploads\ImageService; use BookStack\Uploads\ImageService;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
class Cloner class Cloner
{ {
protected ReferenceChangeContext $referenceChangeContext;
public function __construct( public function __construct(
protected PageRepo $pageRepo, protected PageRepo $pageRepo,
protected ChapterRepo $chapterRepo, protected ChapterRepo $chapterRepo,
protected BookRepo $bookRepo, protected BookRepo $bookRepo,
protected ImageService $imageService, protected ImageService $imageService,
protected ReferenceUpdater $referenceUpdater,
) { ) {
$this->referenceChangeContext = new ReferenceChangeContext();
} }
/** /**
* Clone the given page into the given parent using the provided name. * Clone the given page into the given parent using the provided name.
*/ */
public function clonePage(Page $original, Entity $parent, string $newName): Page public function clonePage(Page $original, Entity $parent, string $newName): Page
{
$context = $this->newReferenceChangeContext();
$page = $this->createPageClone($original, $parent, $newName);
$this->referenceUpdater->changeReferencesUsingContext($context);
return $page;
}
protected function createPageClone(Page $original, Entity $parent, string $newName): Page
{ {
$copyPage = $this->pageRepo->getNewDraftPage($parent); $copyPage = $this->pageRepo->getNewDraftPage($parent);
$pageData = $this->entityToInputData($original); $pageData = $this->entityToInputData($original);
$pageData['name'] = $newName; $pageData['name'] = $newName;
return $this->pageRepo->publishDraft($copyPage, $pageData); $newPage = $this->pageRepo->publishDraft($copyPage, $pageData);
$this->referenceChangeContext->add($original, $newPage);
return $newPage;
} }
/** /**
@@ -44,6 +61,14 @@ class Cloner
* Clones all child pages. * Clones all child pages.
*/ */
public function cloneChapter(Chapter $original, Book $parent, string $newName): Chapter public function cloneChapter(Chapter $original, Book $parent, string $newName): Chapter
{
$context = $this->newReferenceChangeContext();
$chapter = $this->createChapterClone($original, $parent, $newName);
$this->referenceUpdater->changeReferencesUsingContext($context);
return $chapter;
}
protected function createChapterClone(Chapter $original, Book $parent, string $newName): Chapter
{ {
$chapterDetails = $this->entityToInputData($original); $chapterDetails = $this->entityToInputData($original);
$chapterDetails['name'] = $newName; $chapterDetails['name'] = $newName;
@@ -65,6 +90,14 @@ class Cloner
* Clones all child chapters and pages. * Clones all child chapters and pages.
*/ */
public function cloneBook(Book $original, string $newName): Book public function cloneBook(Book $original, string $newName): Book
{
$context = $this->newReferenceChangeContext();
$book = $this->createBookClone($original, $newName);
$this->referenceUpdater->changeReferencesUsingContext($context);
return $book;
}
protected function createBookClone(Book $original, string $newName): Book
{ {
$bookDetails = $this->entityToInputData($original); $bookDetails = $this->entityToInputData($original);
$bookDetails['name'] = $newName; $bookDetails['name'] = $newName;
@@ -155,4 +188,10 @@ class Cloner
return $tags; return $tags;
} }
protected function newReferenceChangeContext(): ReferenceChangeContext
{
$this->referenceChangeContext = new ReferenceChangeContext();
return $this->referenceChangeContext;
}
} }

View File

@@ -0,0 +1,19 @@
<?php
namespace BookStack\References;
use BookStack\Entities\Models\Entity;
class ReferenceChangeContext
{
/**
* Entity pairs where the first is the old entity and the second is the new entity.
* @var array<array{0: Entity, 1: Entity}>
*/
protected array $changes = [];
public function add(Entity $oldEntity, Entity $newEntity): void
{
$this->changes[] = [$oldEntity, $newEntity];
}
}

View File

@@ -30,6 +30,14 @@ class ReferenceUpdater
} }
} }
public function changeReferencesUsingContext(ReferenceChangeContext $context): void
{
// TODO
// We should probably have references by this point, so we could use those for efficient
// discovery instead of scanning each item within the context.
}
/** /**
* @return Reference[] * @return Reference[]
*/ */