]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExports/ZipImportReferences.php
Merge branch 'docker-simplify' into development
[bookstack] / app / Exports / ZipExports / ZipImportReferences.php
1 <?php
2
3 namespace BookStack\Exports\ZipExports;
4
5 use BookStack\App\Model;
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\BaseRepo;
11 use BookStack\Entities\Repos\PageRepo;
12 use BookStack\Exports\ZipExports\Models\ZipExportBook;
13 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
14 use BookStack\Exports\ZipExports\Models\ZipExportPage;
15 use BookStack\Uploads\Attachment;
16 use BookStack\Uploads\Image;
17 use BookStack\Uploads\ImageResizer;
18
19 class ZipImportReferences
20 {
21     /** @var Page[] */
22     protected array $pages = [];
23     /** @var Chapter[] */
24     protected array $chapters = [];
25     /** @var Book[] */
26     protected array $books = [];
27     /** @var Attachment[] */
28     protected array $attachments = [];
29     /** @var Image[] */
30     protected array $images = [];
31
32     /** @var array<string, Model> */
33     protected array $referenceMap = [];
34
35     /** @var array<int, ZipExportPage> */
36     protected array $zipExportPageMap = [];
37     /** @var array<int, ZipExportChapter> */
38     protected array $zipExportChapterMap = [];
39     /** @var array<int, ZipExportBook> */
40     protected array $zipExportBookMap = [];
41
42     public function __construct(
43         protected ZipReferenceParser $parser,
44         protected BaseRepo $baseRepo,
45         protected PageRepo $pageRepo,
46         protected ImageResizer $imageResizer,
47     ) {
48     }
49
50     protected function addReference(string $type, Model $model, ?int $importId): void
51     {
52         if ($importId) {
53             $key = $type . ':' . $importId;
54             $this->referenceMap[$key] = $model;
55         }
56     }
57
58     public function addPage(Page $page, ZipExportPage $exportPage): void
59     {
60         $this->pages[] = $page;
61         $this->zipExportPageMap[$page->id] = $exportPage;
62         $this->addReference('page', $page, $exportPage->id);
63     }
64
65     public function addChapter(Chapter $chapter, ZipExportChapter $exportChapter): void
66     {
67         $this->chapters[] = $chapter;
68         $this->zipExportChapterMap[$chapter->id] = $exportChapter;
69         $this->addReference('chapter', $chapter, $exportChapter->id);
70     }
71
72     public function addBook(Book $book, ZipExportBook $exportBook): void
73     {
74         $this->books[] = $book;
75         $this->zipExportBookMap[$book->id] = $exportBook;
76         $this->addReference('book', $book, $exportBook->id);
77     }
78
79     public function addAttachment(Attachment $attachment, ?int $importId): void
80     {
81         $this->attachments[] = $attachment;
82         $this->addReference('attachment', $attachment, $importId);
83     }
84
85     public function addImage(Image $image, ?int $importId): void
86     {
87         $this->images[] = $image;
88         $this->addReference('image', $image, $importId);
89     }
90
91     protected function handleReference(string $type, int $id): ?string
92     {
93         $key = $type . ':' . $id;
94         $model = $this->referenceMap[$key] ?? null;
95         if ($model instanceof Entity) {
96             return $model->getUrl();
97         } else if ($model instanceof Image) {
98             if ($model->type === 'gallery') {
99                 $this->imageResizer->loadGalleryThumbnailsForImage($model, false);
100                 return $model->thumbs['display'] ?? $model->url;
101             }
102
103             return $model->url;
104         } else if ($model instanceof Attachment) {
105             return $model->getUrl(false);
106         }
107
108         return null;
109     }
110
111     public function replaceReferences(): void
112     {
113         foreach ($this->books as $book) {
114             $exportBook = $this->zipExportBookMap[$book->id];
115             $content = $exportBook->description_html ?? '';
116             $parsed = $this->parser->parseReferences($content, $this->handleReference(...));
117
118             $this->baseRepo->update($book, [
119                 'description_html' => $parsed,
120             ]);
121         }
122
123         foreach ($this->chapters as $chapter) {
124             $exportChapter = $this->zipExportChapterMap[$chapter->id];
125             $content = $exportChapter->description_html ?? '';
126             $parsed = $this->parser->parseReferences($content, $this->handleReference(...));
127
128             $this->baseRepo->update($chapter, [
129                 'description_html' => $parsed,
130             ]);
131         }
132
133         foreach ($this->pages as $page) {
134             $exportPage = $this->zipExportPageMap[$page->id];
135             $contentType = $exportPage->markdown ? 'markdown' : 'html';
136             $content = $exportPage->markdown ?: ($exportPage->html ?: '');
137             $parsed = $this->parser->parseReferences($content, $this->handleReference(...));
138
139             $this->pageRepo->setContentFromInput($page, [
140                 $contentType => $parsed,
141             ]);
142         }
143     }
144
145
146     /**
147      * @return Image[]
148      */
149     public function images(): array
150     {
151         return $this->images;
152     }
153
154     /**
155      * @return Attachment[]
156      */
157     public function attachments(): array
158     {
159         return $this->attachments;
160     }
161 }