From: nchoudhary@logicmines.in Date: Fri, 25 Apr 2025 07:18:34 +0000 (+0530) Subject: Develop functionality to import ZIP files. Create an API controller and define a... X-Git-Url: http://source.bookstackapp.com/bookstack/commitdiff_plain/5fa728f28a0c4f09649da7b653dd66260e49a596?hp=-c Develop functionality to import ZIP files. Create an API controller and define a route entry for handling the import process. Implement logic to read the list of files within the ZIP, process the directory structure, and automatically create associated pages, chapters, and books based on the ZIP file's contents. --- 5fa728f28a0c4f09649da7b653dd66260e49a596 diff --git a/app/Exports/Controllers/ImportApiController.php b/app/Exports/Controllers/ImportApiController.php new file mode 100644 index 000000000..682d340b3 --- /dev/null +++ b/app/Exports/Controllers/ImportApiController.php @@ -0,0 +1,121 @@ +middleware('can:content-import'); + } + + /** + * List existing imports visible to the user. + */ + public function list(): JsonResponse + { + $imports = $this->imports->getVisibleImports(); + + return response()->json([ + 'status' => 'success', + 'imports' => $imports, + ]); + } + + /** + * Upload, validate and store an import file. + */ + public function upload(Request $request): JsonResponse + { + $this->validate($request, [ + 'file' => ['required', ...AttachmentService::getFileValidationRules()] + ]); + + $file = $request->file('file'); + + try { + $import = $this->imports->storeFromUpload($file); + } catch (ZipValidationException $exception) { + return response()->json([ + 'status' => 'error', + 'message' => 'Validation failed', + 'errors' => $exception->errors, + ], 422); + } + + return response()->json([ + 'status' => 'success', + 'import' => $import, + ], 201); + } + + /** + * Show details of a pending import. + */ + public function read(int $id): JsonResponse + { + $import = $this->imports->findVisible($id); + + return response()->json([ + 'status' => 'success', + 'import' => $import, + 'data' => $import->decodeMetadata(), + ]); + } + + /** + * Run the import process. + */ + public function create(int $id, Request $request): JsonResponse + { + $import = $this->imports->findVisible($id); + $parent = null; + + if ($import->type === 'page' || $import->type === 'chapter') { + $data = $this->validate($request, [ + 'parent' => ['required', 'string'], + ]); + $parent = $data['parent']; + } + + try { + $entity = $this->imports->runImport($import, $parent); + } catch (ZipImportException $exception) { + return response()->json([ + 'status' => 'error', + 'message' => 'Import failed', + 'errors' => $exception->errors, + ], 500); + } + + return response()->json([ + 'status' => 'success', + 'entity' => $entity, + ]); + } + + /** + * Delete a pending import. + */ + public function delete(int $id): JsonResponse + { + $import = $this->imports->findVisible($id); + $this->imports->deleteImport($import); + + return response()->json([ + 'status' => 'success', + 'message' => 'Import deleted successfully', + ]); + } +} \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 710364855..bd00ea4b0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -92,3 +92,9 @@ Route::get('content-permissions/{contentType}/{contentId}', [ContentPermissionAp Route::put('content-permissions/{contentType}/{contentId}', [ContentPermissionApiController::class, 'update']); Route::get('audit-log', [AuditLogApiController::class, 'list']); + +Route::get('import', [ExportControllers\ImportApiController::class, 'list']); +Route::post('import', [ExportControllers\ImportApiController::class, 'upload']); +Route::get('import/{id}', [ExportControllers\ImportApiController::class, 'read']); +Route::post('import/{id}/create', [ExportControllers\ImportApiController::class, 'create']); +Route::delete('import/{id}', [ExportControllers\ImportApiController::class, 'destroy']); \ No newline at end of file