3 namespace BookStack\Http\Controllers;
5 use Illuminate\Filesystem\Filesystem as File;
6 use Illuminate\Http\Request;
7 use Illuminate\Support\Facades\Auth;
8 use Intervention\Image\Facades\Image as ImageTool;
9 use Illuminate\Support\Facades\DB;
10 use BookStack\Http\Requests;
12 use BookStack\Repos\PageRepo;
14 class ImageController extends Controller
20 * ImageController constructor.
24 public function __construct(Image $image, File $file)
26 $this->image = $image;
28 parent::__construct();
33 * Get all images, Paginated
35 * @return \Illuminate\Http\JsonResponse
37 public function getAll($page = 0)
40 $images = DB::table('images')->orderBy('created_at', 'desc')
41 ->skip($page * $pageSize)->take($pageSize)->get();
42 foreach ($images as $image) {
43 $image->thumbnail = $this->getThumbnail($image, 150, 150);
45 $hasMore = count(DB::table('images')->orderBy('created_at', 'desc')
46 ->skip(($page + 1) * $pageSize)->take($pageSize)->get()) > 0;
47 return response()->json([
54 * Get the thumbnail for an image.
60 public function getThumbnail($image, $width = 220, $height = 220)
62 $explodedPath = explode('/', $image->url);
63 array_splice($explodedPath, 4, 0, ['thumbs-' . $width . '-' . $height]);
64 $thumbPath = implode('/', $explodedPath);
65 $thumbFilePath = public_path() . $thumbPath;
67 // Return the thumbnail url path if already exists
68 if (file_exists($thumbFilePath)) {
72 // Otherwise create the thumbnail
73 $thumb = ImageTool::make(public_path() . $image->url);
74 $thumb->fit($width, $height);
76 // Create thumbnail folder if it does not exist
77 if (!file_exists(dirname($thumbFilePath))) {
78 mkdir(dirname($thumbFilePath), 0775, true);
82 $thumb->save($thumbFilePath);
87 * Handles image uploads for use on pages.
88 * @param Request $request
89 * @return \Illuminate\Http\JsonResponse
91 public function upload(Request $request)
93 $this->checkPermission('image-create');
94 $imageUpload = $request->file('file');
95 $name = str_replace(' ', '-', $imageUpload->getClientOriginalName());
96 $storageName = substr(sha1(time()), 0, 10) . '-' . $name;
97 $imagePath = '/uploads/images/' . Date('Y-m-M') . '/';
98 $storagePath = public_path() . $imagePath;
99 $fullPath = $storagePath . $storageName;
100 while (file_exists($fullPath)) {
101 $storageName = substr(sha1(rand()), 0, 3) . $storageName;
102 $fullPath = $storagePath . $storageName;
104 $imageUpload->move($storagePath, $storageName);
105 // Create and save image object
106 $this->image->name = $name;
107 $this->image->url = $imagePath . $storageName;
108 $this->image->created_by = Auth::user()->id;
109 $this->image->updated_by = Auth::user()->id;
110 $this->image->save();
111 $this->image->thumbnail = $this->getThumbnail($this->image, 150, 150);
112 return response()->json($this->image);
116 * Update image details
118 * @param Request $request
119 * @return \Illuminate\Http\JsonResponse
121 public function update($imageId, Request $request)
123 $this->checkPermission('image-update');
124 $this->validate($request, [
125 'name' => 'required|min:2|string'
127 $image = $this->image->findOrFail($imageId);
128 $image->fill($request->all());
130 return response()->json($this->image);
134 * Deletes an image and all thumbnail/image files
135 * @param PageRepo $pageRepo
136 * @param Request $request
138 * @return \Illuminate\Http\JsonResponse
140 public function destroy(PageRepo $pageRepo, Request $request, $id)
142 $this->checkPermission('image-delete');
143 $image = $this->image->findOrFail($id);
145 // Check if this image is used on any pages
146 $pageSearch = $pageRepo->searchForImage($image->url);
147 $isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true);
148 if ($pageSearch !== false && !$isForced) {
149 return response()->json($pageSearch, 400);
153 $folder = public_path() . dirname($image->url);
154 $fileName = basename($image->url);
157 foreach (glob($folder . '/*') as $file) {
159 $thumbName = $file . '/' . $fileName;
160 if (file_exists($file)) {
163 // Remove thumb folder if empty
164 if (count(glob($file . '/*')) === 0) {
170 // Delete file and database entry
171 unlink($folder . '/' . $fileName);
174 // Delete parent folder if empty
175 if (count(glob($folder . '/*')) === 0) {
178 return response()->json('Image Deleted');