3 namespace BookStack\Exports;
5 use BookStack\Uploads\Attachment;
6 use BookStack\Uploads\AttachmentService;
7 use Illuminate\Support\Str;
12 * References for attachments by attachment ID.
13 * @var array<int, string>
15 protected array $attachmentRefsById = [];
17 public function __construct(
18 protected AttachmentService $attachmentService,
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.
27 public function referenceForAttachment(Attachment $attachment): string
29 if (isset($this->attachmentRefsById[$attachment->id])) {
30 return $this->attachmentRefsById[$attachment->id];
34 $fileName = Str::random(20) . '.' . $attachment->extension;
35 } while (in_array($fileName, $this->attachmentRefsById));
37 $this->attachmentRefsById[$attachment->id] = $fileName;
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.
47 public function extractEach(callable $callback): void
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);