3 namespace BookStack\Exports;
5 use BookStack\Entities\Models\Entity;
6 use BookStack\Entities\Queries\EntityQueries;
7 use BookStack\Exceptions\FileUploadException;
8 use BookStack\Exceptions\ZipExportException;
9 use BookStack\Exceptions\ZipImportException;
10 use BookStack\Exceptions\ZipValidationException;
11 use BookStack\Exports\ZipExports\Models\ZipExportBook;
12 use BookStack\Exports\ZipExports\Models\ZipExportChapter;
13 use BookStack\Exports\ZipExports\Models\ZipExportPage;
14 use BookStack\Exports\ZipExports\ZipExportReader;
15 use BookStack\Exports\ZipExports\ZipExportValidator;
16 use BookStack\Exports\ZipExports\ZipImportRunner;
17 use BookStack\Uploads\FileStorage;
18 use Illuminate\Database\Eloquent\Collection;
19 use Symfony\Component\HttpFoundation\File\UploadedFile;
23 public function __construct(
24 protected FileStorage $storage,
25 protected ZipImportRunner $importer,
26 protected EntityQueries $entityQueries,
31 * @return Collection<Import>
33 public function getVisibleImports(): Collection
35 $query = Import::query();
37 if (!userCan('settings-manage')) {
38 $query->where('created_by', user()->id);
44 public function findVisible(int $id): Import
46 $query = Import::query();
48 if (!userCan('settings-manage')) {
49 $query->where('created_by', user()->id);
52 return $query->findOrFail($id);
56 * @throws FileUploadException
57 * @throws ZipValidationException
58 * @throws ZipExportException
60 public function storeFromUpload(UploadedFile $file): Import
62 $zipPath = $file->getRealPath();
63 $reader = new ZipExportReader($zipPath);
65 $errors = (new ZipExportValidator($reader))->validate();
67 throw new ZipValidationException($errors);
70 $exportModel = $reader->decodeDataToExportModel();
72 $import = new Import();
73 $import->type = match (get_class($exportModel)) {
74 ZipExportPage::class => 'page',
75 ZipExportChapter::class => 'chapter',
76 ZipExportBook::class => 'book',
79 $import->name = $exportModel->name;
80 $import->created_by = user()->id;
81 $import->size = filesize($zipPath);
83 $exportModel->metadataOnly();
84 $import->metadata = json_encode($exportModel);
86 $path = $this->storage->uploadFile(
88 'uploads/files/imports/',
93 $import->path = $path;
100 * @throws ZipValidationException|ZipImportException
102 public function runImport(Import $import, ?string $parent = null): ?Entity
105 if ($import->type === 'page' || $import->type === 'chapter') {
106 $parentModel = $parent ? $this->entityQueries->findVisibleByStringIdentifier($parent) : null;
109 return $this->importer->run($import, $parentModel);
112 public function deleteImport(Import $import): void
114 $this->storage->delete($import->path);