3 namespace BookStack\Exports\ZipExports;
5 use BookStack\Exports\ZipExports\Models\ZipExportBook;
6 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
7 use BookStack\Exports\ZipExports\Models\ZipExportPage;
10 class ZipExportValidator
12 public function __construct(
13 protected string $zipPath,
17 public function validate(): array
19 // Validate file exists
20 if (!file_exists($this->zipPath) || !is_readable($this->zipPath)) {
21 return ['format' => trans('errors.import_zip_cant_read')];
24 // Validate file is valid zip
25 $zip = new \ZipArchive();
26 $opened = $zip->open($this->zipPath, ZipArchive::RDONLY);
27 if ($opened !== true) {
28 return ['format' => trans('errors.import_zip_cant_read')];
31 // Validate json data exists, including metadata
32 $jsonData = $zip->getFromName('data.json') ?: '';
33 $importData = json_decode($jsonData, true);
35 return ['format' => trans('errors.import_zip_cant_decode_data')];
38 $helper = new ZipValidationHelper($zip);
40 if (isset($importData['book'])) {
41 $modelErrors = ZipExportBook::validate($helper, $importData['book']);
43 } else if (isset($importData['chapter'])) {
44 $modelErrors = ZipExportChapter::validate($helper, $importData['chapter']);
45 $keyPrefix = 'chapter';
46 } else if (isset($importData['page'])) {
47 $modelErrors = ZipExportPage::validate($helper, $importData['page']);
50 return ['format' => trans('errors.import_zip_no_data')];
54 return $this->flattenModelErrors($modelErrors, $keyPrefix);
57 protected function flattenModelErrors(array $errors, string $keyPrefix): array
61 foreach ($errors as $key => $error) {
62 if (is_array($error)) {
63 $flattened = array_merge($flattened, $this->flattenModelErrors($error, $keyPrefix . '.' . $key));
65 $flattened[$keyPrefix . '.' . $key] = $error;