1 <?php namespace BookStack\Http\Controllers;
3 use BookStack\Exceptions\FileUploadException;
5 use BookStack\Repos\PageRepo;
6 use BookStack\Services\FileService;
7 use Illuminate\Http\Request;
9 use BookStack\Http\Requests;
11 class FileController extends Controller
13 protected $fileService;
18 * FileController constructor.
19 * @param FileService $fileService
21 * @param PageRepo $pageRepo
23 public function __construct(FileService $fileService, File $file, PageRepo $pageRepo)
25 $this->fileService = $fileService;
27 $this->pageRepo = $pageRepo;
32 * Endpoint at which files are uploaded to.
33 * @param Request $request
35 public function upload(Request $request)
37 $this->validate($request, [
38 'uploaded_to' => 'required|integer|exists:pages,id',
39 'file' => 'required|file'
42 $pageId = $request->get('uploaded_to');
43 $page = $this->pageRepo->getById($pageId);
45 $this->checkPermission('file-create-all');
46 $this->checkOwnablePermission('page-update', $page);
48 $uploadedFile = $request->file('file');
51 $file = $this->fileService->saveNewUpload($uploadedFile, $pageId);
52 } catch (FileUploadException $e) {
53 return response($e->getMessage(), 500);
56 return response()->json($file);
60 * Update an uploaded file.
62 * @param Request $request
65 public function uploadUpdate($fileId, Request $request)
67 $this->validate($request, [
68 'uploaded_to' => 'required|integer|exists:pages,id',
69 'file' => 'required|file'
72 $pageId = $request->get('uploaded_to');
73 $page = $this->pageRepo->getById($pageId);
74 $file = $this->file->findOrFail($fileId);
76 $this->checkOwnablePermission('page-update', $page);
77 $this->checkOwnablePermission('file-create', $file);
79 if (intval($pageId) !== intval($file->uploaded_to)) {
80 return $this->jsonError('Page mismatch during attached file update');
83 $uploadedFile = $request->file('file');
86 $file = $this->fileService->saveUpdatedUpload($uploadedFile, $file);
87 } catch (FileUploadException $e) {
88 return response($e->getMessage(), 500);
91 return response()->json($file);
95 * Update the details of an existing file.
97 * @param Request $request
100 public function update($fileId, Request $request)
102 $this->validate($request, [
103 'uploaded_to' => 'required|integer|exists:pages,id',
104 'name' => 'string|max:255',
108 $pageId = $request->get('uploaded_to');
109 $page = $this->pageRepo->getById($pageId);
110 $file = $this->file->findOrFail($fileId);
112 $this->checkOwnablePermission('page-update', $page);
113 $this->checkOwnablePermission('file-create', $file);
115 if (intval($pageId) !== intval($file->uploaded_to)) {
116 return $this->jsonError('Page mismatch during attachment update');
119 $file = $this->fileService->updateFile($file, $request->all());
124 * Attach a link to a page as a file.
125 * @param Request $request
128 public function attachLink(Request $request)
130 $this->validate($request, [
131 'uploaded_to' => 'required|integer|exists:pages,id',
132 'name' => 'string|max:255',
133 'link' => 'url|max:255'
136 $pageId = $request->get('uploaded_to');
137 $page = $this->pageRepo->getById($pageId);
139 $this->checkPermission('file-create-all');
140 $this->checkOwnablePermission('page-update', $page);
142 $fileName = $request->get('name');
143 $link = $request->get('link');
144 $file = $this->fileService->saveNewFromLink($fileName, $link, $pageId);
146 return response()->json($file);
150 * Get the files for a specific page.
154 public function listForPage($pageId)
156 $page = $this->pageRepo->getById($pageId);
157 $this->checkOwnablePermission('page-view', $page);
158 return response()->json($page->files);
162 * Update the file sorting.
164 * @param Request $request
167 public function sortForPage($pageId, Request $request)
169 $this->validate($request, [
170 'files' => 'required|array',
171 'files.*.id' => 'required|integer',
173 $page = $this->pageRepo->getById($pageId);
174 $this->checkOwnablePermission('page-update', $page);
176 $files = $request->get('files');
177 $this->fileService->updateFileOrderWithinPage($files, $pageId);
178 return response()->json(['message' => 'Attachment order updated']);
182 * Get a file from storage.
185 public function get($fileId)
187 $file = $this->file->findOrFail($fileId);
188 $page = $this->pageRepo->getById($file->uploaded_to);
189 $this->checkOwnablePermission('page-view', $page);
191 if ($file->external) {
192 return redirect($file->path);
195 $fileContents = $this->fileService->getFile($file);
196 return response($fileContents, 200, [
197 'Content-Type' => 'application/octet-stream',
198 'Content-Disposition' => 'attachment; filename="'. $file->getFileName() .'"'
203 * Delete a specific file in the system.
207 public function delete($fileId)
209 $file = $this->file->findOrFail($fileId);
210 $this->checkOwnablePermission('file-delete', $file);
211 $this->fileService->deleteFile($file);
212 return response()->json(['message' => 'Attachment deleted']);