]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExportReferences.php
19672db0a0ebe1dff1058e68b9d1e45cadc6146a
[bookstack] / app / Exports / ZipExportReferences.php
1 <?php
2
3 namespace BookStack\Exports;
4
5 use BookStack\App\Model;
6 use BookStack\Entities\Models\Page;
7 use BookStack\Exports\ZipExportModels\ZipExportAttachment;
8 use BookStack\Exports\ZipExportModels\ZipExportImage;
9 use BookStack\Exports\ZipExportModels\ZipExportModel;
10 use BookStack\Exports\ZipExportModels\ZipExportPage;
11 use BookStack\Uploads\Attachment;
12 use BookStack\Uploads\Image;
13
14 class ZipExportReferences
15 {
16     /** @var ZipExportPage[] */
17     protected array $pages = [];
18     protected array $books = [];
19     protected array $chapters = [];
20
21     /** @var ZipExportAttachment[] */
22     protected array $attachments = [];
23
24     /** @var ZipExportImage[] */
25     protected array $images = [];
26
27     public function __construct(
28         protected ZipReferenceParser $parser,
29     ) {
30     }
31
32     public function addPage(ZipExportPage $page): void
33     {
34         if ($page->id) {
35             $this->pages[$page->id] = $page;
36         }
37
38         foreach ($page->attachments as $attachment) {
39             if ($attachment->id) {
40                 $this->attachments[$attachment->id] = $attachment;
41             }
42         }
43     }
44
45     public function buildReferences(ZipExportFiles $files): void
46     {
47         // TODO - Parse page MD & HTML
48         foreach ($this->pages as $page) {
49             $page->html = $this->parser->parse($page->html ?? '', function (Model $model) use ($files, $page) {
50                 return $this->handleModelReference($model, $page, $files);
51             });
52             // TODO - markdown
53         }
54
55 //        dd('end');
56         // TODO - Parse chapter desc html
57         // TODO - Parse book desc html
58     }
59
60     protected function handleModelReference(Model $model, ZipExportModel $exportModel, ZipExportFiles $files): ?string
61     {
62         // TODO - References to other entities
63
64         // Handle attachment references
65         // No permission check needed here since they would only already exist in this
66         // reference context if already allowed via their entity access.
67         if ($model instanceof Attachment) {
68             if (isset($this->attachments[$model->id])) {
69                 return "[[bsexport:attachment:{$model->id}]]";
70             }
71             return null;
72         }
73
74         // Handle image references
75         if ($model instanceof Image) {
76             // Only handle gallery and drawio images
77             if ($model->type !== 'gallery' && $model->type !== 'drawio') {
78                 return null;
79             }
80
81             // We don't expect images to be part of book/chapter content
82             if (!($exportModel instanceof ZipExportPage)) {
83                 return null;
84             }
85
86             $page = $model->getPage();
87             if ($page && userCan('view', $page)) {
88                 if (!isset($this->images[$model->id])) {
89                     $exportImage = ZipExportImage::fromModel($model, $files);
90                     $this->images[$model->id] = $exportImage;
91                     $exportModel->images[] = $exportImage;
92                 }
93                 return "[[bsexport:image:{$model->id}]]";
94             }
95             return null;
96         }
97
98         return null;
99     }
100 }