3 namespace BookStack\Exports\ZipExports;
5 use BookStack\App\Model;
6 use BookStack\Exports\ZipExports\Models\ZipExportAttachment;
7 use BookStack\Exports\ZipExports\Models\ZipExportImage;
8 use BookStack\Exports\ZipExports\Models\ZipExportModel;
9 use BookStack\Exports\ZipExports\Models\ZipExportPage;
10 use BookStack\Uploads\Attachment;
11 use BookStack\Uploads\Image;
13 class ZipExportReferences
15 /** @var ZipExportPage[] */
16 protected array $pages = [];
17 protected array $books = [];
18 protected array $chapters = [];
20 /** @var ZipExportAttachment[] */
21 protected array $attachments = [];
23 /** @var ZipExportImage[] */
24 protected array $images = [];
26 public function __construct(
27 protected ZipReferenceParser $parser,
31 public function addPage(ZipExportPage $page): void
34 $this->pages[$page->id] = $page;
37 foreach ($page->attachments as $attachment) {
38 if ($attachment->id) {
39 $this->attachments[$attachment->id] = $attachment;
44 public function buildReferences(ZipExportFiles $files): void
46 // Parse page content first
47 foreach ($this->pages as $page) {
48 $handler = function (Model $model) use ($files, $page) {
49 return $this->handleModelReference($model, $page, $files);
52 $page->html = $this->parser->parse($page->html ?? '', $handler);
53 if ($page->markdown) {
54 $page->markdown = $this->parser->parse($page->markdown, $handler);
59 // TODO - Parse chapter desc html
60 // TODO - Parse book desc html
63 protected function handleModelReference(Model $model, ZipExportModel $exportModel, ZipExportFiles $files): ?string
65 // TODO - References to other entities
67 // Handle attachment references
68 // No permission check needed here since they would only already exist in this
69 // reference context if already allowed via their entity access.
70 if ($model instanceof Attachment) {
71 if (isset($this->attachments[$model->id])) {
72 return "[[bsexport:attachment:{$model->id}]]";
77 // Handle image references
78 if ($model instanceof Image) {
79 // Only handle gallery and drawio images
80 if ($model->type !== 'gallery' && $model->type !== 'drawio') {
84 // We don't expect images to be part of book/chapter content
85 if (!($exportModel instanceof ZipExportPage)) {
89 $page = $model->getPage();
90 if ($page && userCan('view', $page)) {
91 if (!isset($this->images[$model->id])) {
92 $exportImage = ZipExportImage::fromModel($model, $files);
93 $this->images[$model->id] = $exportImage;
94 $exportModel->images[] = $exportImage;
96 return "[[bsexport:image:{$model->id}]]";