]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExportBuilder.php
ZIP Export: Started building link/ref handling
[bookstack] / app / Exports / ZipExportBuilder.php
1 <?php
2
3 namespace BookStack\Exports;
4
5 use BookStack\Entities\Models\Page;
6 use BookStack\Exceptions\ZipExportException;
7 use BookStack\Exports\ZipExportModels\ZipExportPage;
8 use ZipArchive;
9
10 class ZipExportBuilder
11 {
12     protected array $data = [];
13
14     public function __construct(
15         protected ZipExportFiles $files,
16         protected ZipExportReferences $references,
17     ) {
18     }
19
20     /**
21      * @throws ZipExportException
22      */
23     public function buildForPage(Page $page): string
24     {
25         $exportPage = ZipExportPage::fromModel($page, $this->files);
26         $this->data['page'] = $exportPage;
27
28         $this->references->addPage($exportPage);
29
30         return $this->build();
31     }
32
33     /**
34      * @throws ZipExportException
35      */
36     protected function build(): string
37     {
38         $this->references->buildReferences();
39
40         $this->data['exported_at'] = date(DATE_ATOM);
41         $this->data['instance'] = [
42             'version'       => trim(file_get_contents(base_path('version'))),
43             'id_ciphertext' => encrypt('bookstack'),
44         ];
45
46         $zipFile = tempnam(sys_get_temp_dir(), 'bszip-');
47         $zip = new ZipArchive();
48         $opened = $zip->open($zipFile, ZipArchive::CREATE);
49         if ($opened !== true) {
50             throw new ZipExportException('Failed to create zip file for export.');
51         }
52
53         $zip->addFromString('data.json', json_encode($this->data));
54         $zip->addEmptyDir('files');
55
56         $toRemove = [];
57         $this->files->extractEach(function ($filePath, $fileRef) use ($zip, &$toRemove) {
58             $zip->addFile($filePath, "files/$fileRef");
59             $toRemove[] = $filePath;
60         });
61
62         $zip->close();
63
64         foreach ($toRemove as $file) {
65             unlink($file);
66         }
67
68         return $zipFile;
69     }
70 }