]> BookStack Code Mirror - bookstack/blob - app/Exports/ImportRepo.php
3265e1c80dc006bded4f3e030e202bc2542d25a7
[bookstack] / app / Exports / ImportRepo.php
1 <?php
2
3 namespace BookStack\Exports;
4
5 use BookStack\Exceptions\FileUploadException;
6 use BookStack\Exceptions\ZipExportException;
7 use BookStack\Exceptions\ZipValidationException;
8 use BookStack\Exports\ZipExports\Models\ZipExportBook;
9 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
10 use BookStack\Exports\ZipExports\Models\ZipExportPage;
11 use BookStack\Exports\ZipExports\ZipExportReader;
12 use BookStack\Exports\ZipExports\ZipExportValidator;
13 use BookStack\Uploads\FileStorage;
14 use Illuminate\Database\Eloquent\Collection;
15 use Symfony\Component\HttpFoundation\File\UploadedFile;
16
17 class ImportRepo
18 {
19     public function __construct(
20         protected FileStorage $storage,
21     ) {
22     }
23
24     /**
25      * @return Collection<Import>
26      */
27     public function getVisibleImports(): Collection
28     {
29         $query = Import::query();
30
31         if (!userCan('settings-manage')) {
32             $query->where('created_by', user()->id);
33         }
34
35         return $query->get();
36     }
37
38     public function findVisible(int $id): Import
39     {
40         $query = Import::query();
41
42         if (!userCan('settings-manage')) {
43             $query->where('created_by', user()->id);
44         }
45
46         return $query->findOrFail($id);
47     }
48
49     /**
50      * @throws FileUploadException
51      * @throws ZipValidationException
52      * @throws ZipExportException
53      */
54     public function storeFromUpload(UploadedFile $file): Import
55     {
56         $zipPath = $file->getRealPath();
57
58         $errors = (new ZipExportValidator($zipPath))->validate();
59         if ($errors) {
60             throw new ZipValidationException($errors);
61         }
62
63         $reader = new ZipExportReader($zipPath);
64         $exportModel = $reader->decodeDataToExportModel();
65
66         $import = new Import();
67         $import->type = match (get_class($exportModel)) {
68             ZipExportPage::class => 'page',
69             ZipExportChapter::class => 'chapter',
70             ZipExportBook::class => 'book',
71         };
72
73         $import->name = $exportModel->name;
74         $import->created_by = user()->id;
75         $import->size = filesize($zipPath);
76
77         $exportModel->metadataOnly();
78         $import->metadata = json_encode($exportModel);
79
80         $path = $this->storage->uploadFile(
81             $file,
82             'uploads/files/imports/',
83             '',
84             'zip'
85         );
86
87         $import->path = $path;
88         $import->save();
89
90         return $import;
91     }
92
93     public function runImport(Import $import, ?string $parent = null)
94     {
95         // TODO - Download import zip (if needed)
96         // TODO - Validate zip file again
97         // TODO - Check permissions before (create for main item, create for children, create for related items [image, attachments])
98     }
99
100     public function deleteImport(Import $import): void
101     {
102         $this->storage->delete($import->path);
103         $import->delete();
104     }
105 }