]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExportFiles.php
ZIP Export: Expanded page & added base attachment handling
[bookstack] / app / Exports / ZipExportFiles.php
1 <?php
2
3 namespace BookStack\Exports;
4
5 use BookStack\Uploads\Attachment;
6 use BookStack\Uploads\AttachmentService;
7 use Illuminate\Support\Str;
8
9 class ZipExportFiles
10 {
11     /**
12      * References for attachments by attachment ID.
13      * @var array<int, string>
14      */
15     protected array $attachmentRefsById = [];
16
17     public function __construct(
18         protected AttachmentService $attachmentService,
19     ) {
20     }
21
22     /**
23      * Gain a reference to the given attachment instance.
24      * This is expected to be a file-based attachment that the user
25      * has visibility of, no permission/access checks are performed here.
26      */
27     public function referenceForAttachment(Attachment $attachment): string
28     {
29         if (isset($this->attachmentRefsById[$attachment->id])) {
30             return $this->attachmentRefsById[$attachment->id];
31         }
32
33         do {
34             $fileName = Str::random(20) . '.' . $attachment->extension;
35         } while (in_array($fileName, $this->attachmentRefsById));
36
37         $this->attachmentRefsById[$attachment->id] = $fileName;
38
39         return $fileName;
40     }
41
42     /**
43      * Extract each of the ZIP export tracked files.
44      * Calls the given callback for each tracked file, passing a temporary
45      * file reference of the file contents, and the zip-local tracked reference.
46      */
47     public function extractEach(callable $callback): void
48     {
49         foreach ($this->attachmentRefsById as $attachmentId => $ref) {
50             $attachment = Attachment::query()->find($attachmentId);
51             $stream = $this->attachmentService->streamAttachmentFromStorage($attachment);
52             $tmpFile = tempnam(sys_get_temp_dir(), 'bszipfile-');
53             $tmpFileStream = fopen($tmpFile, 'w');
54             stream_copy_to_stream($stream, $tmpFileStream);
55             $callback($tmpFile, $ref);
56         }
57     }
58 }