]> BookStack Code Mirror - bookstack/blob - app/Entities/Tools/Cloner.php
Added ability to copy/clone chapters
[bookstack] / app / Entities / Tools / Cloner.php
1 <?php
2
3 namespace BookStack\Entities\Tools;
4
5 use BookStack\Actions\Tag;
6 use BookStack\Entities\Models\Book;
7 use BookStack\Entities\Models\Chapter;
8 use BookStack\Entities\Models\Entity;
9 use BookStack\Entities\Models\Page;
10 use BookStack\Entities\Repos\ChapterRepo;
11 use BookStack\Entities\Repos\PageRepo;
12
13 class Cloner
14 {
15
16     /**
17      * @var PageRepo
18      */
19     protected $pageRepo;
20
21     /**
22      * @var ChapterRepo
23      */
24     protected $chapterRepo;
25
26     public function __construct(PageRepo $pageRepo, ChapterRepo $chapterRepo)
27     {
28         $this->pageRepo = $pageRepo;
29         $this->chapterRepo = $chapterRepo;
30     }
31
32     /**
33      * Clone the given page into the given parent using the provided name.
34      */
35     public function clonePage(Page $original, Entity $parent, string $newName): Page
36     {
37         $copyPage = $this->pageRepo->getNewDraftPage($parent);
38         $pageData = $original->getAttributes();
39
40         // Update name & tags
41         $pageData['name'] = $newName;
42         $pageData['tags'] = $this->entityTagsToInputArray($original);
43
44         return $this->pageRepo->publishDraft($copyPage, $pageData);
45     }
46
47     /**
48      * Clone the given page into the given parent using the provided name.
49      * Clones all child pages.
50      */
51     public function cloneChapter(Chapter $original, Book $parent, string $newName): Chapter
52     {
53         $chapterDetails = $original->getAttributes();
54         $chapterDetails['name'] = $newName;
55         $chapterDetails['tags'] = $this->entityTagsToInputArray($original);
56
57         $copyChapter = $this->chapterRepo->create($chapterDetails, $parent);
58
59         if (userCan('page-create', $copyChapter)) {
60             /** @var Page $page */
61             foreach ($original->getVisiblePages() as $page) {
62                 $this->clonePage($page, $copyChapter, $page->name);
63             }
64         }
65
66         return $copyChapter;
67     }
68
69     /**
70      * Convert the tags on the given entity to the raw format
71      * that's used for incoming request data.
72      */
73     protected function entityTagsToInputArray(Entity $entity): array
74     {
75         $tags = [];
76
77         /** @var Tag $tag */
78         foreach ($entity->tags as $tag) {
79             $tags[] = ['name' => $tag->name, 'value' => $tag->value];
80         }
81
82         return $tags;
83     }
84
85 }