]> BookStack Code Mirror - bookstack/blob - app/Exports/ZipExports/ZipExportValidator.php
dd56f3e70a8e7d4b75583cfc35d5454dd3011edc
[bookstack] / app / Exports / ZipExports / ZipExportValidator.php
1 <?php
2
3 namespace BookStack\Exports\ZipExports;
4
5 use BookStack\Exports\ZipExports\Models\ZipExportBook;
6 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
7 use BookStack\Exports\ZipExports\Models\ZipExportPage;
8 use ZipArchive;
9
10 class ZipExportValidator
11 {
12     public function __construct(
13         protected string $zipPath,
14     ) {
15     }
16
17     public function validate(): array
18     {
19         // Validate file exists
20         if (!file_exists($this->zipPath) || !is_readable($this->zipPath)) {
21             return ['format' => trans('errors.import_zip_cant_read')];
22         }
23
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')];
29         }
30
31         // Validate json data exists, including metadata
32         $jsonData = $zip->getFromName('data.json') ?: '';
33         $importData = json_decode($jsonData, true);
34         if (!$importData) {
35             return ['format' => trans('errors.import_zip_cant_decode_data')];
36         }
37
38         $helper = new ZipValidationHelper($zip);
39
40         if (isset($importData['book'])) {
41             $modelErrors = ZipExportBook::validate($helper, $importData['book']);
42             $keyPrefix = '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']);
48             $keyPrefix = 'page';
49         } else {
50             return ['format' => trans('errors.import_zip_no_data')];
51         }
52
53
54         return $this->flattenModelErrors($modelErrors, $keyPrefix);
55     }
56
57     protected function flattenModelErrors(array $errors, string $keyPrefix): array
58     {
59         $flattened = [];
60
61         foreach ($errors as $key => $error) {
62             if (is_array($error)) {
63                 $flattened = array_merge($flattened, $this->flattenModelErrors($error, $keyPrefix . '.' . $key));
64             } else {
65                 $flattened[$keyPrefix . '.' . $key] = $error;
66             }
67         }
68
69         return $flattened;
70     }
71 }