1313use BookStack \Entities \Repos \ChapterRepo ;
1414use BookStack \Entities \Repos \PageRepo ;
1515use BookStack \Permissions \Permission ;
16+ use BookStack \References \ReferenceChangeContext ;
17+ use BookStack \References \ReferenceUpdater ;
1618use BookStack \Uploads \Image ;
1719use BookStack \Uploads \ImageService ;
1820use Illuminate \Http \UploadedFile ;
1921
2022class Cloner
2123{
24+ protected ReferenceChangeContext $ referenceChangeContext ;
25+
2226 public function __construct (
2327 protected PageRepo $ pageRepo ,
2428 protected ChapterRepo $ chapterRepo ,
2529 protected BookRepo $ bookRepo ,
2630 protected ImageService $ imageService ,
31+ protected ReferenceUpdater $ referenceUpdater ,
2732 ) {
33+ $ this ->referenceChangeContext = new ReferenceChangeContext ();
2834 }
2935
3036 /**
3137 * Clone the given page into the given parent using the provided name.
3238 */
3339 public function clonePage (Page $ original , Entity $ parent , string $ newName ): Page
40+ {
41+ $ context = $ this ->newReferenceChangeContext ();
42+ $ page = $ this ->createPageClone ($ original , $ parent , $ newName );
43+ $ this ->referenceUpdater ->changeReferencesUsingContext ($ context );
44+ return $ page ;
45+ }
46+
47+ protected function createPageClone (Page $ original , Entity $ parent , string $ newName ): Page
3448 {
3549 $ copyPage = $ this ->pageRepo ->getNewDraftPage ($ parent );
3650 $ pageData = $ this ->entityToInputData ($ original );
3751 $ pageData ['name ' ] = $ newName ;
3852
39- return $ this ->pageRepo ->publishDraft ($ copyPage , $ pageData );
53+ $ newPage = $ this ->pageRepo ->publishDraft ($ copyPage , $ pageData );
54+ $ this ->referenceChangeContext ->add ($ original , $ newPage );
55+
56+ return $ newPage ;
4057 }
4158
4259 /**
4360 * Clone the given page into the given parent using the provided name.
4461 * Clones all child pages.
4562 */
4663 public function cloneChapter (Chapter $ original , Book $ parent , string $ newName ): Chapter
64+ {
65+ $ context = $ this ->newReferenceChangeContext ();
66+ $ chapter = $ this ->createChapterClone ($ original , $ parent , $ newName );
67+ $ this ->referenceUpdater ->changeReferencesUsingContext ($ context );
68+ return $ chapter ;
69+ }
70+
71+ protected function createChapterClone (Chapter $ original , Book $ parent , string $ newName ): Chapter
4772 {
4873 $ chapterDetails = $ this ->entityToInputData ($ original );
4974 $ chapterDetails ['name ' ] = $ newName ;
@@ -53,10 +78,12 @@ public function cloneChapter(Chapter $original, Book $parent, string $newName):
5378 if (userCan (Permission::PageCreate, $ copyChapter )) {
5479 /** @var Page $page */
5580 foreach ($ original ->getVisiblePages () as $ page ) {
56- $ this ->clonePage ($ page , $ copyChapter , $ page ->name );
81+ $ this ->createPageClone ($ page , $ copyChapter , $ page ->name );
5782 }
5883 }
5984
85+ $ this ->referenceChangeContext ->add ($ original , $ copyChapter );
86+
6087 return $ copyChapter ;
6188 }
6289
@@ -65,6 +92,14 @@ public function cloneChapter(Chapter $original, Book $parent, string $newName):
6592 * Clones all child chapters and pages.
6693 */
6794 public function cloneBook (Book $ original , string $ newName ): Book
95+ {
96+ $ context = $ this ->newReferenceChangeContext ();
97+ $ book = $ this ->createBookClone ($ original , $ newName );
98+ $ this ->referenceUpdater ->changeReferencesUsingContext ($ context );
99+ return $ book ;
100+ }
101+
102+ protected function createBookClone (Book $ original , string $ newName ): Book
68103 {
69104 $ bookDetails = $ this ->entityToInputData ($ original );
70105 $ bookDetails ['name ' ] = $ newName ;
@@ -76,11 +111,11 @@ public function cloneBook(Book $original, string $newName): Book
76111 $ directChildren = $ original ->getDirectVisibleChildren ();
77112 foreach ($ directChildren as $ child ) {
78113 if ($ child instanceof Chapter && userCan (Permission::ChapterCreate, $ copyBook )) {
79- $ this ->cloneChapter ($ child , $ copyBook , $ child ->name );
114+ $ this ->createChapterClone ($ child , $ copyBook , $ child ->name );
80115 }
81116
82117 if ($ child instanceof Page && !$ child ->draft && userCan (Permission::PageCreate, $ copyBook )) {
83- $ this ->clonePage ($ child , $ copyBook , $ child ->name );
118+ $ this ->createPageClone ($ child , $ copyBook , $ child ->name );
84119 }
85120 }
86121
@@ -92,6 +127,8 @@ public function cloneBook(Book $original, string $newName): Book
92127 }
93128 }
94129
130+ $ this ->referenceChangeContext ->add ($ original , $ copyBook );
131+
95132 return $ copyBook ;
96133 }
97134
@@ -155,4 +192,10 @@ protected function entityTagsToInputArray(Entity $entity): array
155192
156193 return $ tags ;
157194 }
195+
196+ protected function newReferenceChangeContext (): ReferenceChangeContext
197+ {
198+ $ this ->referenceChangeContext = new ReferenceChangeContext ();
199+ return $ this ->referenceChangeContext ;
200+ }
158201}
0 commit comments