]> BookStack Code Mirror - bookstack/blobdiff - app/Exports/ImportRepo.php
TypeScript: Updated compile target, addressed issues
[bookstack] / app / Exports / ImportRepo.php
index c8157967bc3783a3f3abf02471e67819deda8b05..e030a88d261f2745d96ee6bd97e7291d783d7d69 100644 (file)
@@ -2,37 +2,96 @@
 
 namespace BookStack\Exports;
 
+use BookStack\Activity\ActivityType;
+use BookStack\Entities\Models\Entity;
+use BookStack\Entities\Queries\EntityQueries;
+use BookStack\Exceptions\FileUploadException;
+use BookStack\Exceptions\ZipExportException;
+use BookStack\Exceptions\ZipImportException;
 use BookStack\Exceptions\ZipValidationException;
+use BookStack\Exports\ZipExports\Models\ZipExportBook;
+use BookStack\Exports\ZipExports\Models\ZipExportChapter;
+use BookStack\Exports\ZipExports\Models\ZipExportPage;
 use BookStack\Exports\ZipExports\ZipExportReader;
 use BookStack\Exports\ZipExports\ZipExportValidator;
+use BookStack\Exports\ZipExports\ZipImportRunner;
+use BookStack\Facades\Activity;
 use BookStack\Uploads\FileStorage;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\DB;
 use Symfony\Component\HttpFoundation\File\UploadedFile;
 
 class ImportRepo
 {
     public function __construct(
         protected FileStorage $storage,
+        protected ZipImportRunner $importer,
+        protected EntityQueries $entityQueries,
     ) {
     }
 
+    /**
+     * @return Collection<Import>
+     */
+    public function getVisibleImports(): Collection
+    {
+        return $this->queryVisible()->get();
+    }
+
+    public function queryVisible(): Builder
+    {
+        $query = Import::query();
+
+        if (!userCan('settings-manage')) {
+            $query->where('created_by', user()->id);
+        }
+
+        return $query;
+    }
+
+    public function findVisible(int $id): Import
+    {
+        $query = Import::query();
+
+        if (!userCan('settings-manage')) {
+            $query->where('created_by', user()->id);
+        }
+
+        return $query->findOrFail($id);
+    }
+
+    /**
+     * @throws FileUploadException
+     * @throws ZipValidationException
+     * @throws ZipExportException
+     */
     public function storeFromUpload(UploadedFile $file): Import
     {
         $zipPath = $file->getRealPath();
+        $reader = new ZipExportReader($zipPath);
 
-        $errors = (new ZipExportValidator($zipPath))->validate();
+        $errors = (new ZipExportValidator($reader))->validate();
         if ($errors) {
             throw new ZipValidationException($errors);
         }
 
-        $zipEntityInfo = (new ZipExportReader($zipPath))->getEntityInfo();
+        $exportModel = $reader->decodeDataToExportModel();
+
         $import = new Import();
-        $import->name = $zipEntityInfo['name'];
-        $import->book_count = $zipEntityInfo['book_count'];
-        $import->chapter_count = $zipEntityInfo['chapter_count'];
-        $import->page_count = $zipEntityInfo['page_count'];
+        $import->type = match (get_class($exportModel)) {
+            ZipExportPage::class => 'page',
+            ZipExportChapter::class => 'chapter',
+            ZipExportBook::class => 'book',
+        };
+
+        $import->name = $exportModel->name;
         $import->created_by = user()->id;
         $import->size = filesize($zipPath);
 
+        $exportModel->metadataOnly();
+        $import->metadata = json_encode($exportModel);
+
         $path = $this->storage->uploadFile(
             $file,
             'uploads/files/imports/',
@@ -43,6 +102,42 @@ class ImportRepo
         $import->path = $path;
         $import->save();
 
+        Activity::add(ActivityType::IMPORT_CREATE, $import);
+
         return $import;
     }
+
+    /**
+     * @throws ZipImportException
+     */
+    public function runImport(Import $import, ?string $parent = null): Entity
+    {
+        $parentModel = null;
+        if ($import->type === 'page' || $import->type === 'chapter') {
+            $parentModel = $parent ? $this->entityQueries->findVisibleByStringIdentifier($parent) : null;
+        }
+
+        DB::beginTransaction();
+        try {
+            $model = $this->importer->run($import, $parentModel);
+        } catch (ZipImportException $e) {
+            DB::rollBack();
+            $this->importer->revertStoredFiles();
+            throw $e;
+        }
+
+        DB::commit();
+        $this->deleteImport($import);
+        Activity::add(ActivityType::IMPORT_RUN, $import);
+
+        return $model;
+    }
+
+    public function deleteImport(Import $import): void
+    {
+        $this->storage->delete($import->path);
+        $import->delete();
+
+        Activity::add(ActivityType::IMPORT_DELETE, $import);
+    }
 }