]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/AttachmentController.php
Update Localization.php in Middleware with "no" tag for estimate.
[bookstack] / app / Http / Controllers / AttachmentController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Entities\Repos\PageRepo;
4 use BookStack\Exceptions\FileUploadException;
5 use BookStack\Exceptions\NotFoundException;
6 use BookStack\Uploads\Attachment;
7 use BookStack\Uploads\AttachmentService;
8 use Exception;
9 use Illuminate\Contracts\Filesystem\FileNotFoundException;
10 use Illuminate\Http\Request;
11 use Illuminate\Support\MessageBag;
12 use Illuminate\Validation\ValidationException;
13
14 class AttachmentController extends Controller
15 {
16     protected $attachmentService;
17     protected $attachment;
18     protected $pageRepo;
19
20     /**
21      * AttachmentController constructor.
22      */
23     public function __construct(AttachmentService $attachmentService, Attachment $attachment, PageRepo $pageRepo)
24     {
25         $this->attachmentService = $attachmentService;
26         $this->attachment = $attachment;
27         $this->pageRepo = $pageRepo;
28         parent::__construct();
29     }
30
31
32     /**
33      * Endpoint at which attachments are uploaded to.
34      * @throws ValidationException
35      * @throws NotFoundException
36      */
37     public function upload(Request $request)
38     {
39         $this->validate($request, [
40             'uploaded_to' => 'required|integer|exists:pages,id',
41             'file' => 'required|file'
42         ]);
43
44         $pageId = $request->get('uploaded_to');
45         $page = $this->pageRepo->getById($pageId);
46
47         $this->checkPermission('attachment-create-all');
48         $this->checkOwnablePermission('page-update', $page);
49
50         $uploadedFile = $request->file('file');
51
52         try {
53             $attachment = $this->attachmentService->saveNewUpload($uploadedFile, $pageId);
54         } catch (FileUploadException $e) {
55             return response($e->getMessage(), 500);
56         }
57
58         return response()->json($attachment);
59     }
60
61     /**
62      * Update an uploaded attachment.
63      * @throws ValidationException
64      */
65     public function uploadUpdate(Request $request, $attachmentId)
66     {
67         $this->validate($request, [
68             'file' => 'required|file'
69         ]);
70
71         $attachment = $this->attachment->newQuery()->findOrFail($attachmentId);
72         $this->checkOwnablePermission('view', $attachment->page);
73         $this->checkOwnablePermission('page-update', $attachment->page);
74         $this->checkOwnablePermission('attachment-create', $attachment);
75
76         $uploadedFile = $request->file('file');
77
78         try {
79             $attachment = $this->attachmentService->saveUpdatedUpload($uploadedFile, $attachment);
80         } catch (FileUploadException $e) {
81             return response($e->getMessage(), 500);
82         }
83
84         return response()->json($attachment);
85     }
86
87     /**
88      * Get the update form for an attachment.
89      * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
90      */
91     public function getUpdateForm(string $attachmentId)
92     {
93         $attachment = $this->attachment->findOrFail($attachmentId);
94
95         $this->checkOwnablePermission('page-update', $attachment->page);
96         $this->checkOwnablePermission('attachment-create', $attachment);
97
98         return view('attachments.manager-edit-form', [
99             'attachment' => $attachment,
100         ]);
101     }
102
103     /**
104      * Update the details of an existing file.
105      */
106     public function update(Request $request, string $attachmentId)
107     {
108         $attachment = $this->attachment->newQuery()->findOrFail($attachmentId);
109
110         try {
111             $this->validate($request, [
112                 'attachment_edit_name' => 'required|string|min:1|max:255',
113                 'attachment_edit_url' =>  'string|min:1|max:255'
114             ]);
115         } catch (ValidationException $exception) {
116             return response()->view('attachments.manager-edit-form', array_merge($request->only(['attachment_edit_name', 'attachment_edit_url']), [
117                 'attachment' => $attachment,
118                 'errors' => new MessageBag($exception->errors()),
119             ]), 422);
120         }
121
122         $this->checkOwnablePermission('view', $attachment->page);
123         $this->checkOwnablePermission('page-update', $attachment->page);
124         $this->checkOwnablePermission('attachment-create', $attachment);
125
126         $attachment = $this->attachmentService->updateFile($attachment, [
127             'name' => $request->get('attachment_edit_name'),
128             'link' => $request->get('attachment_edit_url'),
129         ]);
130
131         return view('attachments.manager-edit-form', [
132             'attachment' => $attachment,
133         ]);
134     }
135
136     /**
137      * Attach a link to a page.
138      * @throws NotFoundException
139      */
140     public function attachLink(Request $request)
141     {
142         $pageId = $request->get('attachment_link_uploaded_to');
143
144         try {
145             $this->validate($request, [
146                 'attachment_link_uploaded_to' => 'required|integer|exists:pages,id',
147                 'attachment_link_name' => 'required|string|min:1|max:255',
148                 'attachment_link_url' =>  'required|string|min:1|max:255'
149             ]);
150         } catch (ValidationException $exception) {
151             return response()->view('attachments.manager-link-form', array_merge($request->only(['attachment_link_name', 'attachment_link_url']), [
152                 'pageId' => $pageId,
153                 'errors' => new MessageBag($exception->errors()),
154             ]), 422);
155         }
156
157         $page = $this->pageRepo->getById($pageId);
158
159         $this->checkPermission('attachment-create-all');
160         $this->checkOwnablePermission('page-update', $page);
161
162         $attachmentName = $request->get('attachment_link_name');
163         $link = $request->get('attachment_link_url');
164         $attachment = $this->attachmentService->saveNewFromLink($attachmentName, $link, $pageId);
165
166         return view('attachments.manager-link-form', [
167             'pageId' => $pageId,
168         ]);
169     }
170
171     /**
172      * Get the attachments for a specific page.
173      */
174     public function listForPage(int $pageId)
175     {
176         $page = $this->pageRepo->getById($pageId);
177         $this->checkOwnablePermission('page-view', $page);
178         return view('attachments.manager-list', [
179             'attachments' => $page->attachments->all(),
180         ]);
181     }
182
183     /**
184      * Update the attachment sorting.
185      * @throws ValidationException
186      * @throws NotFoundException
187      */
188     public function sortForPage(Request $request, int $pageId)
189     {
190         $this->validate($request, [
191             'order' => 'required|array',
192         ]);
193         $page = $this->pageRepo->getById($pageId);
194         $this->checkOwnablePermission('page-update', $page);
195
196         $attachmentOrder = $request->get('order');
197         $this->attachmentService->updateFileOrderWithinPage($attachmentOrder, $pageId);
198         return response()->json(['message' => trans('entities.attachments_order_updated')]);
199     }
200
201     /**
202      * Get an attachment from storage.
203      * @throws FileNotFoundException
204      * @throws NotFoundException
205      */
206     public function get(string $attachmentId)
207     {
208         $attachment = $this->attachment->findOrFail($attachmentId);
209         try {
210             $page = $this->pageRepo->getById($attachment->uploaded_to);
211         } catch (NotFoundException $exception) {
212             throw new NotFoundException(trans('errors.attachment_not_found'));
213         }
214
215         $this->checkOwnablePermission('page-view', $page);
216
217         if ($attachment->external) {
218             return redirect($attachment->path);
219         }
220
221         $attachmentContents = $this->attachmentService->getAttachmentFromStorage($attachment);
222         return $this->downloadResponse($attachmentContents, $attachment->getFileName());
223     }
224
225     /**
226      * Delete a specific attachment in the system.
227      * @throws Exception
228      */
229     public function delete(string $attachmentId)
230     {
231         $attachment = $this->attachment->findOrFail($attachmentId);
232         $this->checkOwnablePermission('attachment-delete', $attachment);
233         $this->attachmentService->deleteFile($attachment);
234         return response()->json(['message' => trans('entities.attachments_deleted')]);
235     }
236 }