3 namespace BookStack\Exports\ZipExports;
5 use BookStack\Exceptions\ZipExportException;
6 use BookStack\Exports\ZipExports\Models\ZipExportBook;
7 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
8 use BookStack\Exports\ZipExports\Models\ZipExportModel;
9 use BookStack\Exports\ZipExports\Models\ZipExportPage;
10 use BookStack\Util\WebSafeMimeSniffer;
15 protected ZipArchive $zip;
16 protected bool $open = false;
18 public function __construct(
19 protected string $zipPath,
21 $this->zip = new ZipArchive();
25 * @throws ZipExportException
27 protected function open(): void
33 // Validate file exists
34 if (!file_exists($this->zipPath) || !is_readable($this->zipPath)) {
35 throw new ZipExportException(trans('errors.import_zip_cant_read'));
38 // Validate file is valid zip
39 $opened = $this->zip->open($this->zipPath, ZipArchive::RDONLY);
40 if ($opened !== true) {
41 throw new ZipExportException(trans('errors.import_zip_cant_read'));
47 public function close(): void
56 * @throws ZipExportException
58 public function readData(): array
62 // Validate json data exists, including metadata
63 $jsonData = $this->zip->getFromName('data.json') ?: '';
64 $importData = json_decode($jsonData, true);
66 throw new ZipExportException(trans('errors.import_zip_cant_decode_data'));
72 public function fileExists(string $fileName): bool
74 return $this->zip->statName("files/{$fileName}") !== false;
78 * @return false|resource
80 public function streamFile(string $fileName)
82 return $this->zip->getStream("files/{$fileName}");
86 * Sniff the mime type from the file of given name.
88 public function sniffFileMime(string $fileName): string
90 $stream = $this->streamFile($fileName);
91 $sniffContent = fread($stream, 2000);
93 return (new WebSafeMimeSniffer())->sniff($sniffContent);
97 * @throws ZipExportException
99 public function decodeDataToExportModel(): ZipExportBook|ZipExportChapter|ZipExportPage
101 $data = $this->readData();
102 if (isset($data['book'])) {
103 return ZipExportBook::fromArray($data['book']);
104 } else if (isset($data['chapter'])) {
105 return ZipExportChapter::fromArray($data['chapter']);
106 } else if (isset($data['page'])) {
107 return ZipExportPage::fromArray($data['page']);
110 throw new ZipExportException("Could not identify content in ZIP file data.");