]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExportBuilder.php
2b8b45d0d2a01d3259fc9a6f707df621699eeae0
[bookstack] / app / Exports / ZipExportBuilder.php
1 <?php
2
3 namespace BookStack\Exports;
4
5 use BookStack\Activity\Models\Tag;
6 use BookStack\Entities\Models\Page;
7 use BookStack\Exceptions\ZipExportException;
8 use BookStack\Uploads\Attachment;
9 use ZipArchive;
10
11 class ZipExportBuilder
12 {
13     protected array $data = [];
14
15     public function __construct(
16         protected ZipExportFiles $files
17     ) {
18     }
19
20     /**
21      * @throws ZipExportException
22      */
23     public function buildForPage(Page $page): string
24     {
25         $this->data['page'] = $this->convertPage($page);
26         return $this->build();
27     }
28
29     protected function convertPage(Page $page): array
30     {
31         $tags = array_map($this->convertTag(...), $page->tags()->get()->all());
32         $attachments = array_map($this->convertAttachment(...), $page->attachments()->get()->all());
33
34         return [
35             'id'          => $page->id,
36             'name'        => $page->name,
37             'html'        => '', // TODO
38             'markdown'    => '', // TODO
39             'priority'    => $page->priority,
40             'attachments' => $attachments,
41             'images'      => [], // TODO
42             'tags'        => $tags,
43         ];
44     }
45
46     protected function convertAttachment(Attachment $attachment): array
47     {
48         $data = [
49             'name'  => $attachment->name,
50             'order' => $attachment->order,
51         ];
52
53         if ($attachment->external) {
54             $data['link'] = $attachment->path;
55         } else {
56             $data['file'] = $this->files->referenceForAttachment($attachment);
57         }
58
59         return $data;
60     }
61
62     protected function convertTag(Tag $tag): array
63     {
64         return [
65             'name'  => $tag->name,
66             'value' => $tag->value,
67             'order' => $tag->order,
68         ];
69     }
70
71     /**
72      * @throws ZipExportException
73      */
74     protected function build(): string
75     {
76         $this->data['exported_at'] = date(DATE_ATOM);
77         $this->data['instance'] = [
78             'version'       => trim(file_get_contents(base_path('version'))),
79             'id_ciphertext' => encrypt('bookstack'),
80         ];
81
82         $zipFile = tempnam(sys_get_temp_dir(), 'bszip-');
83         $zip = new ZipArchive();
84         $opened = $zip->open($zipFile, ZipArchive::CREATE);
85         if ($opened !== true) {
86             throw new ZipExportException('Failed to create zip file for export.');
87         }
88
89         $zip->addFromString('data.json', json_encode($this->data));
90         $zip->addEmptyDir('files');
91
92         $toRemove = [];
93         $this->files->extractEach(function ($filePath, $fileRef) use ($zip, &$toRemove) {
94             $zip->addFile($filePath, "files/$fileRef");
95             $toRemove[] = $filePath;
96         });
97
98         $zip->close();
99
100         foreach ($toRemove as $file) {
101             unlink($file);
102         }
103
104         return $zipFile;
105     }
106 }