3 namespace BookStack\Exports;
5 use BookStack\Entities\Queries\EntityQueries;
6 use BookStack\Exceptions\FileUploadException;
7 use BookStack\Exceptions\ZipExportException;
8 use BookStack\Exceptions\ZipValidationException;
9 use BookStack\Exports\ZipExports\Models\ZipExportBook;
10 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
11 use BookStack\Exports\ZipExports\Models\ZipExportPage;
12 use BookStack\Exports\ZipExports\ZipExportReader;
13 use BookStack\Exports\ZipExports\ZipExportValidator;
14 use BookStack\Exports\ZipExports\ZipImportRunner;
15 use BookStack\Uploads\FileStorage;
16 use Illuminate\Database\Eloquent\Collection;
17 use Symfony\Component\HttpFoundation\File\UploadedFile;
21 public function __construct(
22 protected FileStorage $storage,
23 protected ZipImportRunner $importer,
24 protected EntityQueries $entityQueries,
29 * @return Collection<Import>
31 public function getVisibleImports(): Collection
33 $query = Import::query();
35 if (!userCan('settings-manage')) {
36 $query->where('created_by', user()->id);
42 public function findVisible(int $id): Import
44 $query = Import::query();
46 if (!userCan('settings-manage')) {
47 $query->where('created_by', user()->id);
50 return $query->findOrFail($id);
54 * @throws FileUploadException
55 * @throws ZipValidationException
56 * @throws ZipExportException
58 public function storeFromUpload(UploadedFile $file): Import
60 $zipPath = $file->getRealPath();
61 $reader = new ZipExportReader($zipPath);
63 $errors = (new ZipExportValidator($reader))->validate();
65 throw new ZipValidationException($errors);
68 $exportModel = $reader->decodeDataToExportModel();
70 $import = new Import();
71 $import->type = match (get_class($exportModel)) {
72 ZipExportPage::class => 'page',
73 ZipExportChapter::class => 'chapter',
74 ZipExportBook::class => 'book',
77 $import->name = $exportModel->name;
78 $import->created_by = user()->id;
79 $import->size = filesize($zipPath);
81 $exportModel->metadataOnly();
82 $import->metadata = json_encode($exportModel);
84 $path = $this->storage->uploadFile(
86 'uploads/files/imports/',
91 $import->path = $path;
98 * @throws ZipValidationException
100 public function runImport(Import $import, ?string $parent = null)
103 if ($import->type === 'page' || $import->type === 'chapter') {
104 $parentModel = $parent ? $this->entityQueries->findVisibleByStringIdentifier($parent) : null;
107 return $this->importer->run($import, $parentModel);
110 public function deleteImport(Import $import): void
112 $this->storage->delete($import->path);