| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Exports; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  | use BookStack\Activity\ActivityType; | 
					
						
							| 
									
										
										
										
											2024-11-11 23:06:46 +08:00
										 |  |  | use BookStack\Entities\Models\Entity; | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  | use BookStack\Entities\Queries\EntityQueries; | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  | use BookStack\Exceptions\FileUploadException; | 
					
						
							|  |  |  | use BookStack\Exceptions\ZipExportException; | 
					
						
							| 
									
										
										
										
											2024-11-11 23:06:46 +08:00
										 |  |  | use BookStack\Exceptions\ZipImportException; | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | use BookStack\Exceptions\ZipValidationException; | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  | use BookStack\Exports\ZipExports\Models\ZipExportBook; | 
					
						
							|  |  |  | use BookStack\Exports\ZipExports\Models\ZipExportChapter; | 
					
						
							|  |  |  | use BookStack\Exports\ZipExports\Models\ZipExportPage; | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | use BookStack\Exports\ZipExports\ZipExportReader; | 
					
						
							|  |  |  | use BookStack\Exports\ZipExports\ZipExportValidator; | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  | use BookStack\Exports\ZipExports\ZipImportRunner; | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  | use BookStack\Facades\Activity; | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | use BookStack\Uploads\FileStorage; | 
					
						
							| 
									
										
										
										
											2024-11-03 22:13:05 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Collection; | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  | use Illuminate\Support\Facades\DB; | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | use Symfony\Component\HttpFoundation\File\UploadedFile; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImportRepo | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     public function __construct( | 
					
						
							|  |  |  |         protected FileStorage $storage, | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |         protected ZipImportRunner $importer, | 
					
						
							|  |  |  |         protected EntityQueries $entityQueries, | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |     ) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-03 22:13:05 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @return Collection<Import> | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getVisibleImports(): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $query = Import::query(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!userCan('settings-manage')) { | 
					
						
							|  |  |  |             $query->where('created_by', user()->id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $query->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function findVisible(int $id): Import | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $query = Import::query(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!userCan('settings-manage')) { | 
					
						
							|  |  |  |             $query->where('created_by', user()->id); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $query->findOrFail($id); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @throws FileUploadException | 
					
						
							|  |  |  |      * @throws ZipValidationException | 
					
						
							|  |  |  |      * @throws ZipExportException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |     public function storeFromUpload(UploadedFile $file): Import | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $zipPath = $file->getRealPath(); | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |         $reader = new ZipExportReader($zipPath); | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |         $errors = (new ZipExportValidator($reader))->validate(); | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |         if ($errors) { | 
					
						
							|  |  |  |             throw new ZipValidationException($errors); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |         $exportModel = $reader->decodeDataToExportModel(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |         $import = new Import(); | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |         $import->type = match (get_class($exportModel)) { | 
					
						
							|  |  |  |             ZipExportPage::class => 'page', | 
					
						
							|  |  |  |             ZipExportChapter::class => 'chapter', | 
					
						
							|  |  |  |             ZipExportBook::class => 'book', | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $import->name = $exportModel->name; | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |         $import->created_by = user()->id; | 
					
						
							|  |  |  |         $import->size = filesize($zipPath); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |         $exportModel->metadataOnly(); | 
					
						
							|  |  |  |         $import->metadata = json_encode($exportModel); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |         $path = $this->storage->uploadFile( | 
					
						
							|  |  |  |             $file, | 
					
						
							|  |  |  |             'uploads/files/imports/', | 
					
						
							|  |  |  |             '', | 
					
						
							|  |  |  |             'zip' | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $import->path = $path; | 
					
						
							|  |  |  |         $import->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  |         Activity::add(ActivityType::IMPORT_CREATE, $import); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  |         return $import; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-03 22:13:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  |      * @throws ZipImportException | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  |     public function runImport(Import $import, ?string $parent = null): Entity | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-11-05 23:41:58 +08:00
										 |  |  |         $parentModel = null; | 
					
						
							|  |  |  |         if ($import->type === 'page' || $import->type === 'chapter') { | 
					
						
							|  |  |  |             $parentModel = $parent ? $this->entityQueries->findVisibleByStringIdentifier($parent) : null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  |         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; | 
					
						
							| 
									
										
										
										
											2024-11-05 21:17:31 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-03 22:13:05 +08:00
										 |  |  |     public function deleteImport(Import $import): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->storage->delete($import->path); | 
					
						
							|  |  |  |         $import->delete(); | 
					
						
							| 
									
										
										
										
											2024-11-14 23:59:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Activity::add(ActivityType::IMPORT_DELETE, $import); | 
					
						
							| 
									
										
										
										
											2024-11-03 22:13:05 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-03 04:48:21 +08:00
										 |  |  | } |