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 // TODO - ensure uploads are deleted on page delete.
38 $this->validate($request, [
39 'uploaded_to' => 'required|integer|exists:pages,id',
40 'file' => 'required|file'
43 $pageId = $request->get('uploaded_to');
44 $page = $this->pageRepo->getById($pageId);
46 $this->checkPermission('file-create-all');
47 $this->checkOwnablePermission('page-update', $page);
49 $uploadedFile = $request->file('file');
52 $file = $this->fileService->saveNewUpload($uploadedFile, $pageId);
53 } catch (FileUploadException $e) {
54 return response($e->getMessage(), 500);
57 return response()->json($file);
61 * Update an uploaded file.
63 * @param Request $request
66 public function uploadUpdate($fileId, Request $request)
68 $this->validate($request, [
69 'uploaded_to' => 'required|integer|exists:pages,id',
70 'file' => 'required|file'
73 $pageId = $request->get('uploaded_to');
74 $page = $this->pageRepo->getById($pageId);
75 $file = $this->file->findOrFail($fileId);
77 $this->checkOwnablePermission('page-update', $page);
78 $this->checkOwnablePermission('file-create', $file);
80 if (intval($pageId) !== intval($file->uploaded_to)) {
81 return $this->jsonError('Page mismatch during attached file update');
84 $uploadedFile = $request->file('file');
87 $file = $this->fileService->saveUpdatedUpload($uploadedFile, $file);
88 } catch (FileUploadException $e) {
89 return response($e->getMessage(), 500);
92 return response()->json($file);
96 * Update the details of an existing file.
98 * @param Request $request
101 public function update($fileId, Request $request)
103 $this->validate($request, [
104 'uploaded_to' => 'required|integer|exists:pages,id',
105 'name' => 'string|max:255',
109 $pageId = $request->get('uploaded_to');
110 $page = $this->pageRepo->getById($pageId);
111 $file = $this->file->findOrFail($fileId);
113 $this->checkOwnablePermission('page-update', $page);
114 $this->checkOwnablePermission('file-create', $file);
116 if (intval($pageId) !== intval($file->uploaded_to)) {
117 return $this->jsonError('Page mismatch during attachment update');
120 $file = $this->fileService->updateFile($file, $request->all());
125 * Attach a link to a page as a file.
126 * @param Request $request
129 public function attachLink(Request $request)
131 $this->validate($request, [
132 'uploaded_to' => 'required|integer|exists:pages,id',
133 'name' => 'string|max:255',
134 'link' => 'url|max:255'
137 $pageId = $request->get('uploaded_to');
138 $page = $this->pageRepo->getById($pageId);
140 $this->checkPermission('file-create-all');
141 $this->checkOwnablePermission('page-update', $page);
143 $fileName = $request->get('name');
144 $link = $request->get('link');
145 $file = $this->fileService->saveNewFromLink($fileName, $link, $pageId);
147 return response()->json($file);
151 * Get the files for a specific page.
155 public function listForPage($pageId)
157 $page = $this->pageRepo->getById($pageId);
158 $this->checkOwnablePermission('page-view', $page);
159 return response()->json($page->files);
163 * Update the file sorting.
165 * @param Request $request
168 public function sortForPage($pageId, Request $request)
170 $this->validate($request, [
171 'files' => 'required|array',
172 'files.*.id' => 'required|integer',
174 $page = $this->pageRepo->getById($pageId);
175 $this->checkOwnablePermission('page-update', $page);
177 $files = $request->get('files');
178 $this->fileService->updateFileOrderWithinPage($files, $pageId);
179 return response()->json(['message' => 'Attachment order updated']);
183 * Get a file from storage.
186 public function get($fileId)
188 $file = $this->file->findOrFail($fileId);
189 $page = $this->pageRepo->getById($file->uploaded_to);
190 $this->checkOwnablePermission('page-view', $page);
192 if ($file->external) {
193 return redirect($file->path);
196 $fileContents = $this->fileService->getFile($file);
197 return response($fileContents, 200, [
198 'Content-Type' => 'application/octet-stream',
199 'Content-Disposition' => 'attachment; filename="'. $file->name .'"'
204 * Delete a specific file in the system.
208 public function delete($fileId)
210 $file = $this->file->findOrFail($fileId);
211 $this->checkOwnablePermission('file-delete', $file);
212 $this->fileService->deleteFile($file);
213 return response()->json(['message' => 'Attachment deleted']);