]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/ImageController.php
Started diversion to not using image manager for cover/system/user
[bookstack] / app / Http / Controllers / ImageController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Entities\Repos\EntityRepo;
4 use BookStack\Exceptions\ImageUploadException;
5 use BookStack\Repos\PageRepo;
6 use BookStack\Uploads\Image;
7 use BookStack\Uploads\ImageRepo;
8 use Illuminate\Filesystem\Filesystem as File;
9 use Illuminate\Http\Request;
10
11 class ImageController extends Controller
12 {
13     protected $image;
14     protected $file;
15     protected $imageRepo;
16
17     /**
18      * ImageController constructor.
19      * @param Image $image
20      * @param File $file
21      * @param ImageRepo $imageRepo
22      */
23     public function __construct(Image $image, File $file, ImageRepo $imageRepo)
24     {
25         $this->image = $image;
26         $this->file = $file;
27         $this->imageRepo = $imageRepo;
28         parent::__construct();
29     }
30
31     /**
32      * Provide an image file from storage.
33      * @param string $path
34      * @return mixed
35      */
36     public function showImage(string $path)
37     {
38         $path = storage_path('uploads/images/' . $path);
39         if (!file_exists($path)) {
40             abort(404);
41         }
42
43         return response()->file($path);
44     }
45
46     /**
47      * Get all images for a specific type, Paginated
48      * @param Request $request
49      * @param string $type
50      * @param int $page
51      * @return \Illuminate\Http\JsonResponse
52      */
53     public function getAllByType(Request $request, $type, $page = 0)
54     {
55         $uploadedToFilter = $request->get('uploaded_to', null);
56
57         // For user profile request, check access to user images
58         if ($type === 'user') {
59             $this->checkPermissionOrCurrentUser('users-manage', $uploadedToFilter ?? 0);
60         }
61
62         $imgData = $this->imageRepo->getPaginatedByType($type, $page, 24, $uploadedToFilter);
63         return response()->json($imgData);
64     }
65
66     /**
67      * Search through images within a particular type.
68      * @param $type
69      * @param int $page
70      * @param Request $request
71      * @return mixed
72      */
73     public function searchByType(Request $request, $type, $page = 0)
74     {
75         $this->validate($request, [
76             'term' => 'required|string'
77         ]);
78
79         $searchTerm = $request->get('term');
80         $imgData = $this->imageRepo->searchPaginatedByType($type, $searchTerm, $page, 24);
81         return response()->json($imgData);
82     }
83
84     public function uploadUserImage(Request $request)
85     {
86         // TODO
87     }
88
89     public function uploadSystemImage(Request $request)
90     {
91         // TODO
92     }
93
94     public function uploadCoverImage(Request $request)
95     {
96         // TODO
97     }
98
99     /**
100      * Upload a draw.io image into the system.
101      * @param Request $request
102      * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
103      */
104     public function uploadDrawioImage(Request $request)
105     {
106         $this->validate($request, [
107             'image' => 'required|string',
108             'uploaded_to' => 'required|integer'
109         ]);
110         $uploadedTo = $request->get('uploaded_to', 0);
111         $page = $this->
112         $this->checkPermission('image-create-all');
113         $imageBase64Data = $request->get('image');
114
115         try {
116             $image = $this->imageRepo->saveDrawing($imageBase64Data, $uploadedTo);
117         } catch (ImageUploadException $e) {
118             return response($e->getMessage(), 500);
119         }
120
121         return response()->json($image);
122     }
123
124     /**
125      * Handles image uploads for use on pages.
126      * @param string $type
127      * @param Request $request
128      * @return \Illuminate\Http\JsonResponse
129      * @throws \Exception
130      */
131     public function uploadByType($type, Request $request)
132     {
133         $this->checkPermission('image-create-all');
134         $this->validate($request, [
135             'file' => 'image_extension|no_double_extension|mimes:jpeg,png,gif,bmp,webp,tiff'
136         ]);
137
138         if (!$this->imageRepo->isValidType($type)) {
139             return $this->jsonError(trans('errors.image_upload_type_error'));
140         }
141
142         $imageUpload = $request->file('file');
143
144         try {
145             $uploadedTo = $request->get('uploaded_to', 0);
146
147             // For user profile request, check access to user images
148             if ($type === 'user') {
149                 $this->checkPermissionOrCurrentUser('users-manage', $uploadedTo ?? 0);
150             }
151
152             $image = $this->imageRepo->saveNew($imageUpload, $type, $uploadedTo);
153         } catch (ImageUploadException $e) {
154             return response($e->getMessage(), 500);
155         }
156
157         return response()->json($image);
158     }
159     /**
160      * Get the content of an image based64 encoded.
161      * @param $id
162      * @return \Illuminate\Http\JsonResponse|mixed
163      */
164     public function getBase64Image($id)
165     {
166         $image = $this->imageRepo->getById($id);
167         $imageData = $this->imageRepo->getImageData($image);
168         if ($imageData === null) {
169             return $this->jsonError("Image data could not be found");
170         }
171         return response()->json([
172             'content' => base64_encode($imageData)
173         ]);
174     }
175
176     /**
177      * Generate a sized thumbnail for an image.
178      * @param $id
179      * @param $width
180      * @param $height
181      * @param $crop
182      * @return \Illuminate\Http\JsonResponse
183      * @throws ImageUploadException
184      * @throws \Exception
185      */
186     public function getThumbnail($id, $width, $height, $crop)
187     {
188         $this->checkPermission('image-create-all');
189         $image = $this->imageRepo->getById($id);
190         $thumbnailUrl = $this->imageRepo->getThumbnail($image, $width, $height, $crop == 'false');
191         return response()->json(['url' => $thumbnailUrl]);
192     }
193
194     /**
195      * Update image details
196      * @param integer $id
197      * @param Request $request
198      * @return \Illuminate\Http\JsonResponse
199      * @throws ImageUploadException
200      * @throws \Exception
201      */
202     public function update($id, Request $request)
203     {
204         $this->validate($request, [
205             'name' => 'required|min:2|string'
206         ]);
207
208         $image = $this->imageRepo->getById($id);
209         $this->checkOwnablePermission('image-update', $image);
210
211         $image = $this->imageRepo->updateImageDetails($image, $request->all());
212         return response()->json($image);
213     }
214
215     /**
216      * Show the usage of an image on pages.
217      * @param \BookStack\Entities\Repos\EntityRepo $entityRepo
218      * @param $id
219      * @return \Illuminate\Http\JsonResponse
220      */
221     public function usage(EntityRepo $entityRepo, $id)
222     {
223         $image = $this->imageRepo->getById($id);
224         $pageSearch = $entityRepo->searchForImage($image->url);
225         return response()->json($pageSearch);
226     }
227
228     /**
229      * Deletes an image and all thumbnail/image files
230      * @param int $id
231      * @return \Illuminate\Http\JsonResponse
232      * @throws \Exception
233      */
234     public function destroy($id)
235     {
236         $image = $this->imageRepo->getById($id);
237         $this->checkOwnablePermission('image-delete', $image);
238
239         $this->imageRepo->destroyImage($image);
240         return response()->json(trans('components.images_deleted'));
241     }
242 }