]> BookStack Code Mirror - bookstack/blob - app/Exports/Controllers/ImportController.php
ZIP Imports: Added high level import run tests
[bookstack] / app / Exports / Controllers / ImportController.php
1 <?php
2
3 declare(strict_types=1);
4
5 namespace BookStack\Exports\Controllers;
6
7 use BookStack\Exceptions\ZipImportException;
8 use BookStack\Exceptions\ZipValidationException;
9 use BookStack\Exports\ImportRepo;
10 use BookStack\Http\Controller;
11 use BookStack\Uploads\AttachmentService;
12 use Illuminate\Http\Request;
13
14 class ImportController extends Controller
15 {
16     public function __construct(
17         protected ImportRepo $imports,
18     ) {
19         $this->middleware('can:content-import');
20     }
21
22     /**
23      * Show the view to start a new import, and also list out the existing
24      * in progress imports that are visible to the user.
25      */
26     public function start()
27     {
28         $imports = $this->imports->getVisibleImports();
29
30         $this->setPageTitle(trans('entities.import'));
31
32         return view('exports.import', [
33             'imports' => $imports,
34             'zipErrors' => session()->pull('validation_errors') ?? [],
35         ]);
36     }
37
38     /**
39      * Upload, validate and store an import file.
40      */
41     public function upload(Request $request)
42     {
43         $this->validate($request, [
44             'file' => ['required', ...AttachmentService::getFileValidationRules()]
45         ]);
46
47         $file = $request->file('file');
48         try {
49             $import = $this->imports->storeFromUpload($file);
50         } catch (ZipValidationException $exception) {
51             return redirect('/import')->with('validation_errors', $exception->errors);
52         }
53
54         return redirect($import->getUrl());
55     }
56
57     /**
58      * Show a pending import, with a form to allow progressing
59      * with the import process.
60      */
61     public function show(int $id)
62     {
63         $import = $this->imports->findVisible($id);
64
65         $this->setPageTitle(trans('entities.import_continue'));
66
67         return view('exports.import-show', [
68             'import' => $import,
69             'data' => $import->decodeMetadata(),
70         ]);
71     }
72
73     /**
74      * Run the import process against an uploaded import ZIP.
75      */
76     public function run(int $id, Request $request)
77     {
78         $import = $this->imports->findVisible($id);
79         $parent = null;
80
81         if ($import->type === 'page' || $import->type === 'chapter') {
82             session()->setPreviousUrl($import->getUrl());
83             $data = $this->validate($request, [
84                 'parent' => ['required', 'string'],
85             ]);
86             $parent = $data['parent'];
87         }
88
89         try {
90             $entity = $this->imports->runImport($import, $parent);
91         } catch (ZipImportException $exception) {
92             return redirect($import->getUrl())->with('import_errors', $exception->errors);
93         }
94
95         return redirect($entity->getUrl());
96     }
97
98     /**
99      * Delete an active pending import from the filesystem and database.
100      */
101     public function delete(int $id)
102     {
103         $import = $this->imports->findVisible($id);
104         $this->imports->deleteImport($import);
105
106         return redirect('/import');
107     }
108 }