1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace WebDevEtc\BlogEtc\Services; |
4
|
|
|
|
5
|
|
|
use Auth; |
6
|
|
|
use Carbon\Carbon; |
7
|
|
|
use Exception; |
8
|
|
|
use File; |
9
|
|
|
use Illuminate\Contracts\Filesystem\Filesystem; |
10
|
|
|
use Illuminate\Http\UploadedFile; |
11
|
|
|
use Illuminate\Support\Str; |
12
|
|
|
use Image; |
13
|
|
|
use Intervention\Image\Constraint; |
14
|
|
|
use RuntimeException; |
15
|
|
|
use Storage; |
16
|
|
|
use WebDevEtc\BlogEtc\Events\BlogPostAdded; |
17
|
|
|
use WebDevEtc\BlogEtc\Events\BlogPostEdited; |
18
|
|
|
use WebDevEtc\BlogEtc\Events\BlogPostWillBeDeleted; |
19
|
|
|
use WebDevEtc\BlogEtc\Events\UploadedImage; |
20
|
|
|
use WebDevEtc\BlogEtc\Helpers; |
21
|
|
|
use WebDevEtc\BlogEtc\Interfaces\LegacyGetImageFileInterface; |
22
|
|
|
use WebDevEtc\BlogEtc\Models\Post; |
23
|
|
|
use WebDevEtc\BlogEtc\Models\UploadedPhoto; |
24
|
|
|
use WebDevEtc\BlogEtc\Repositories\UploadedPhotosRepository; |
25
|
|
|
use WebDevEtc\BlogEtc\Requests\CreateBlogEtcPostRequest; |
26
|
|
|
use WebDevEtc\BlogEtc\Requests\DeleteBlogEtcPostRequest; |
27
|
|
|
//use WebDevEtc\BlogEtc\Requests\PostRequest; |
28
|
|
|
use WebDevEtc\BlogEtc\Requests\UpdateBlogEtcPostRequest; |
29
|
|
|
use WebDevEtc\BlogEtc\Requests\UploadImageRequest; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Class UploadsService. |
33
|
|
|
*/ |
34
|
|
|
class UploadsService |
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* How many iterations to find an available filename, before exception. |
38
|
|
|
* |
39
|
|
|
* @var int |
40
|
|
|
*/ |
41
|
|
|
private static $availableFilenameAttempts = 10; |
42
|
|
|
/** |
43
|
|
|
* @var UploadedPhotosRepository |
44
|
|
|
*/ |
45
|
|
|
private $repository; |
46
|
|
|
|
47
|
|
|
public function __construct(UploadedPhotosRepository $repository) |
48
|
|
|
{ |
49
|
|
|
$this->repository = $repository; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Save a new post. |
54
|
|
|
*/ |
55
|
|
|
public function legacyStorePost(CreateBlogEtcPostRequest $request) |
56
|
|
|
{ |
57
|
|
|
$new_blog_post = new Post($request->all()); |
58
|
|
|
|
59
|
|
|
$this->legacyProcessUploadedImages($request, $new_blog_post); |
60
|
|
|
|
61
|
|
|
if (!$new_blog_post->posted_at) { |
62
|
|
|
$new_blog_post->posted_at = Carbon::now(); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
$new_blog_post->user_id = Auth::user()->id; |
66
|
|
|
$new_blog_post->save(); |
67
|
|
|
|
68
|
|
|
$new_blog_post->categories()->sync($request->categories()); |
69
|
|
|
|
70
|
|
|
Helpers::flashMessage('Added post'); |
71
|
|
|
event(new BlogPostAdded($new_blog_post)); |
72
|
|
|
|
73
|
|
|
return $new_blog_post->editUrl(); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* This uses some legacy code. This will get refactored soon into something nicer. |
78
|
|
|
*/ |
79
|
|
|
public function legacyUpdatePost(UpdateBlogEtcPostRequest $request, $blogPostId) |
80
|
|
|
{ |
81
|
|
|
/** @var Post $post */ |
82
|
|
|
$post = Post::findOrFail($blogPostId); |
83
|
|
|
$post->fill($request->all()); |
84
|
|
|
|
85
|
|
|
$this->legacyProcessUploadedImages($request, $post); |
86
|
|
|
|
87
|
|
|
$post->save(); |
88
|
|
|
$post->categories()->sync($request->categories()); |
89
|
|
|
|
90
|
|
|
Helpers::flashMessage('Updated post'); |
91
|
|
|
event(new BlogPostEdited($post)); |
92
|
|
|
|
93
|
|
|
return $post->editUrl(); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Legacy method - will get updated soon. |
98
|
|
|
* |
99
|
|
|
* Process any uploaded images (for featured image). |
100
|
|
|
* |
101
|
|
|
* @throws Exception |
102
|
|
|
* |
103
|
|
|
* @return array returns an array of details about each file resized |
104
|
|
|
* |
105
|
|
|
* @todo - This class was added after the other main features, so this duplicates some code from the main blog post admin controller (BlogEtcAdminController). For next full release this should be tided up. |
106
|
|
|
*/ |
107
|
|
|
public function legacyProcessUploadedImagesSingle(UploadImageRequest $request) |
108
|
|
|
{ |
109
|
|
|
$this->increaseMemoryLimit(); |
110
|
|
|
$photo = $request->file('upload'); |
111
|
|
|
|
112
|
|
|
$uploaded_image_details = []; |
113
|
|
|
|
114
|
|
|
$sizes_to_upload = $request->get('sizes_to_upload'); |
115
|
|
|
|
116
|
|
|
// now upload a full size - this is a special case, not in the config file. We only store full size images in this class, not as part of the featured blog image uploads. |
117
|
|
|
if (isset($sizes_to_upload['blogetc_full_size']) && 'true' === $sizes_to_upload['blogetc_full_size']) { |
118
|
|
|
$uploaded_image_details['blogetc_full_size'] = $this->legacyUploadAndResize(null, $request->get('image_title'), |
119
|
|
|
'fullsize', $photo); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
foreach ((array) config('blogetc.image_sizes') as $size => $image_size_details) { |
123
|
|
|
if (!isset($sizes_to_upload[$size]) || !$sizes_to_upload[$size] || !$image_size_details['enabled']) { |
124
|
|
|
continue; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
$uploaded_image_details[$size] = $this->legacyUploadAndResize(null, $request->get('image_title'), |
128
|
|
|
$image_size_details, $photo); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
UploadedPhoto::create([ |
132
|
|
|
'image_title' => $request->get('image_title'), |
133
|
|
|
'source' => 'ImageUpload', |
134
|
|
|
'uploader_id' => (int) Auth::id(), |
135
|
|
|
'uploaded_images' => $uploaded_image_details, |
136
|
|
|
]); |
137
|
|
|
|
138
|
|
|
return $uploaded_image_details; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Process any uploaded images (for featured image). |
143
|
|
|
* |
144
|
|
|
* @param $new_blog_post |
145
|
|
|
* |
146
|
|
|
* @throws Exception |
147
|
|
|
* |
148
|
|
|
* @todo - next full release, tidy this up! |
149
|
|
|
*/ |
150
|
|
|
public function legacyProcessUploadedImages(LegacyGetImageFileInterface $request, Post $new_blog_post) |
151
|
|
|
{ |
152
|
|
|
if (!config('blogetc.image_upload_enabled')) { |
153
|
|
|
return; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
$this->increaseMemoryLimit(); |
157
|
|
|
|
158
|
|
|
$uploaded_image_details = []; |
159
|
|
|
|
160
|
|
|
foreach ((array) config('blogetc.image_sizes') as $size => $image_size_details) { |
161
|
|
|
if ($image_size_details['enabled'] && $photo = $request->get_image_file($size)) { |
162
|
|
|
$uploaded_image = $this->legacyUploadAndResize($new_blog_post, $new_blog_post->title, $image_size_details, |
163
|
|
|
$photo); |
164
|
|
|
|
165
|
|
|
$new_blog_post->$size = $uploaded_image['filename']; |
166
|
|
|
$uploaded_image_details[$size] = $uploaded_image; |
167
|
|
|
} |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
// todo: link this to the blogetc_post row. |
171
|
|
|
if (count(array_filter($uploaded_image_details)) > 0) { |
172
|
|
|
UploadedPhoto::create([ |
173
|
|
|
'source' => 'BlogFeaturedImage', |
174
|
|
|
'uploaded_images' => $uploaded_image_details, |
175
|
|
|
]); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param Post $new_blog_post |
181
|
|
|
* @param $suggested_title string - used to help generate the filename |
182
|
|
|
* @param $image_size_details mixed - either an array (with 'w' and 'h') or a string (and it'll be uploaded at full size, no size reduction, but will use this string to generate the filename) |
183
|
|
|
* @param $photo |
184
|
|
|
* |
185
|
|
|
* @throws Exception |
186
|
|
|
* |
187
|
|
|
* @return array |
188
|
|
|
*/ |
189
|
|
|
protected function legacyUploadAndResize(Post $new_blog_post = null, $suggested_title, $image_size_details, $photo) |
190
|
|
|
{ |
191
|
|
|
$image_filename = $this->legacyGetImageFilename($suggested_title, $image_size_details, $photo); |
192
|
|
|
$destinationPath = $this->image_destination_path(); |
193
|
|
|
|
194
|
|
|
$resizedImage = Image::make($photo->getRealPath()); |
195
|
|
|
|
196
|
|
|
if (is_array($image_size_details)) { |
197
|
|
|
$w = $image_size_details['w']; |
198
|
|
|
$h = $image_size_details['h']; |
199
|
|
|
|
200
|
|
|
if (isset($image_size_details['crop']) && $image_size_details['crop']) { |
201
|
|
|
$resizedImage = $resizedImage->fit($w, $h); |
202
|
|
|
} else { |
203
|
|
|
$resizedImage = $resizedImage->resize($w, $h, static function ($constraint) { |
204
|
|
|
$constraint->aspectRatio(); |
205
|
|
|
}); |
206
|
|
|
} |
207
|
|
|
} elseif ('fullsize' === $image_size_details) { |
208
|
|
|
$w = $resizedImage->width(); |
209
|
|
|
$h = $resizedImage->height(); |
210
|
|
|
} else { |
211
|
|
|
throw new Exception('Invalid image_size_details value'); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
$resizedImage->save($destinationPath.'/'.$image_filename, config('blogetc.image_quality', 80)); |
215
|
|
|
|
216
|
|
|
event(new UploadedImage($image_filename, $resizedImage, $new_blog_post, __METHOD__)); |
217
|
|
|
|
218
|
|
|
return [ |
219
|
|
|
'filename' => $image_filename, |
220
|
|
|
'w' => $w, |
221
|
|
|
'h' => $h, |
222
|
|
|
]; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @throws RuntimeException |
227
|
|
|
* |
228
|
|
|
* @return string |
229
|
|
|
*/ |
230
|
|
|
public function image_destination_path() |
231
|
|
|
{ |
232
|
|
|
$path = public_path('/'.config('blogetc.blog_upload_dir')); |
233
|
|
|
$this->check_image_destination_path_is_writable($path); |
234
|
|
|
|
235
|
|
|
return $path; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* Legacy - will be removed |
240
|
|
|
* Check if the image destination directory is writable. |
241
|
|
|
* Throw an exception if it was not writable. |
242
|
|
|
* |
243
|
|
|
* @param $path |
244
|
|
|
* |
245
|
|
|
* @throws RuntimeException |
246
|
|
|
*/ |
247
|
|
|
protected function check_image_destination_path_is_writable($path) |
248
|
|
|
{ |
249
|
|
|
if (!is_writable($path)) { |
250
|
|
|
throw new RuntimeException("Image destination path is not writable ($path)"); |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Legacy function, will get refactored soon into something nicer! |
256
|
|
|
* Get a filename (that doesn't exist) on the filesystem. |
257
|
|
|
* |
258
|
|
|
* Todo: support multiple filesystem locations. |
259
|
|
|
* |
260
|
|
|
* @param $image_size_details - either an array (with w/h attributes) or a string |
|
|
|
|
261
|
|
|
* |
262
|
|
|
* @throws RuntimeException |
263
|
|
|
* |
264
|
|
|
* @return string |
265
|
|
|
*/ |
266
|
|
|
public function legacyGetImageFilename(string $suggested_title, $image_size_details, UploadedFile $photo) |
267
|
|
|
{ |
268
|
|
|
$base = $this->generate_base_filename($suggested_title); |
269
|
|
|
|
270
|
|
|
// $wh will be something like "-1200x300" |
271
|
|
|
$wh = $this->getDimensions($image_size_details); |
272
|
|
|
$ext = '.'.$photo->getClientOriginalExtension(); |
273
|
|
|
|
274
|
|
|
for ($i = 1; $i <= 10; $i++) { |
275
|
|
|
// add suffix if $i>1 |
276
|
|
|
$suffix = $i > 1 ? '-'.str_random(5) : ''; |
277
|
|
|
|
278
|
|
|
$attempt = str_slug($base.$suffix.$wh).$ext; |
279
|
|
|
|
280
|
|
|
if (!File::exists($this->image_destination_path().'/'.$attempt)) { |
281
|
|
|
// filename doesn't exist, let's use it! |
282
|
|
|
return $attempt; |
283
|
|
|
} |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
// too many attempts... |
287
|
|
|
throw new RuntimeException("Unable to find a free filename after $i attempts - aborting now."); |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
/** |
291
|
|
|
* @return string |
292
|
|
|
*/ |
293
|
|
|
protected function generate_base_filename(string $suggested_title) |
294
|
|
|
{ |
295
|
|
|
$base = substr($suggested_title, 0, 100); |
296
|
|
|
if (!$base) { |
297
|
|
|
// if we have an empty string then we should use a random one: |
298
|
|
|
$base = 'image-'.str_random(5); |
299
|
|
|
|
300
|
|
|
return $base; |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
return $base; |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
/** |
307
|
|
|
* Given a filename, return a public url for that asset on the filesystem as defined in the config. |
308
|
|
|
*/ |
309
|
|
|
public static function publicUrl(string $filename): string |
310
|
|
|
{ |
311
|
|
|
return self::disk()->url(config('blogetc.blog_upload_dir').'/'.$filename); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* Disk for filesystem storage. |
316
|
|
|
* |
317
|
|
|
* Set the relevant config file to use things such as S3. |
318
|
|
|
*/ |
319
|
|
|
public static function disk(): Filesystem |
320
|
|
|
{ |
321
|
|
|
return Storage::disk(config('blogetc.image_upload_disk', 'public')); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
// /** |
325
|
|
|
// * Handle an image upload via the upload image section (not blog post featured image). |
326
|
|
|
// * |
327
|
|
|
// * @param $uploadedImage |
328
|
|
|
// * |
329
|
|
|
// * @throws Exception |
330
|
|
|
// */ |
331
|
|
|
// public function processUpload($uploadedImage, string $imageTitle): array |
332
|
|
|
// { |
333
|
|
|
// // to save in db later |
334
|
|
|
// $uploadedImageDetails = []; |
335
|
|
|
// $this->increaseMemoryLimit(); |
336
|
|
|
// |
337
|
|
|
// if (config('blogetc.image_store_full_size')) { |
338
|
|
|
// // Store as full size |
339
|
|
|
// $uploadedImageDetails['blogetc_full_size'] = $this->uploadAndResize( |
340
|
|
|
// null, |
341
|
|
|
// $imageTitle, |
342
|
|
|
// 'fullsize', |
343
|
|
|
// $uploadedImage |
344
|
|
|
// ); |
345
|
|
|
// } |
346
|
|
|
// |
347
|
|
|
// foreach ((array) config('blogetc.image_sizes') as $size => $imageSizeDetails) { |
348
|
|
|
// $uploadedImageDetails[$size] = $this->uploadAndResize( |
349
|
|
|
// null, |
350
|
|
|
// $imageTitle, |
351
|
|
|
// $imageSizeDetails, |
352
|
|
|
// $uploadedImage |
353
|
|
|
// ); |
354
|
|
|
// } |
355
|
|
|
// |
356
|
|
|
// // Store the image data in db: |
357
|
|
|
// $this->storeInDatabase( |
358
|
|
|
// null, |
359
|
|
|
// $imageTitle, |
360
|
|
|
// UploadedPhoto::SOURCE_IMAGE_UPLOAD, |
361
|
|
|
// (int) Auth::id(), |
362
|
|
|
// $uploadedImageDetails |
363
|
|
|
// ); |
364
|
|
|
// |
365
|
|
|
// return $uploadedImageDetails; |
366
|
|
|
// } |
367
|
|
|
|
368
|
|
|
/** |
369
|
|
|
* Small method to increase memory limit. |
370
|
|
|
* This can be defined in the config file. If blogetc.memory_limit is false/null then it won't do anything. |
371
|
|
|
* This is needed though because if you upload a large image it'll not work. |
372
|
|
|
*/ |
373
|
|
|
public function increaseMemoryLimit(): void |
374
|
|
|
{ |
375
|
|
|
// increase memory - change this setting in config file |
376
|
|
|
if (config('blogetc.memory_limit')) { |
377
|
|
|
ini_set('memory_limit', config('blogetc.memory_limit')); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* Resize and store an image. |
383
|
|
|
* |
384
|
|
|
* @param Post $new_blog_post |
385
|
|
|
* @param $suggested_title - used to help generate the filename |
|
|
|
|
386
|
|
|
* @param array|string $imageSizeDetails - either an array (with 'w' and 'h') or a string (and it'll be uploaded at full size, |
387
|
|
|
* no size reduction, but will use this string to generate the filename) |
388
|
|
|
* @param $photo |
389
|
|
|
* |
390
|
|
|
* @throws Exception |
391
|
|
|
*/ |
392
|
|
|
protected function uploadAndResize( |
393
|
|
|
?Post $new_blog_post, |
394
|
|
|
$suggested_title, |
395
|
|
|
$imageSizeDetails, |
396
|
|
|
UploadedFile $photo |
397
|
|
|
): array { |
398
|
|
|
// get the filename/filepath |
399
|
|
|
$image_filename = $this->getImageFilename($suggested_title, $imageSizeDetails, $photo); |
400
|
|
|
$destinationPath = $this->imageDestinationPath(); |
401
|
|
|
|
402
|
|
|
// make image |
403
|
|
|
$resizedImage = Image::make($photo->getRealPath()); |
404
|
|
|
|
405
|
|
|
if (is_array($imageSizeDetails)) { |
406
|
|
|
// resize to these dimensions: |
407
|
|
|
$w = $imageSizeDetails['w']; |
408
|
|
|
$h = $imageSizeDetails['h']; |
409
|
|
|
|
410
|
|
|
if (isset($imageSizeDetails['crop']) && $imageSizeDetails['crop']) { |
411
|
|
|
$resizedImage = $resizedImage->fit($w, $h); |
412
|
|
|
} else { |
413
|
|
|
$resizedImage = $resizedImage->resize($w, $h, static function (Constraint $constraint) { |
414
|
|
|
$constraint->aspectRatio(); |
415
|
|
|
}); |
416
|
|
|
} |
417
|
|
|
} elseif ('fullsize' === $imageSizeDetails) { |
418
|
|
|
// nothing to do here - no resizing needed. |
419
|
|
|
// We just need to set $w/$h with the original w/h values |
420
|
|
|
$w = $resizedImage->width(); |
421
|
|
|
$h = $resizedImage->height(); |
422
|
|
|
} else { |
423
|
|
|
throw new RuntimeException('Invalid image_size_details value of '.$imageSizeDetails); |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
$imageQuality = config('blogetc.image_quality', 80); |
427
|
|
|
$format = pathinfo($image_filename, PATHINFO_EXTENSION); |
428
|
|
|
$resizedImageData = $resizedImage->encode($format, $imageQuality); |
429
|
|
|
$this::disk()->put($destinationPath.'/'.$image_filename, $resizedImageData); |
430
|
|
|
|
431
|
|
|
event(new UploadedImage($image_filename, $resizedImage, $new_blog_post, __METHOD__)); |
432
|
|
|
|
433
|
|
|
return [ |
434
|
|
|
'filename' => $image_filename, |
435
|
|
|
'w' => $w, |
436
|
|
|
'h' => $h, |
437
|
|
|
]; |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* Get a filename (that doesn't exist) on the filesystem. |
442
|
|
|
* |
443
|
|
|
* @param $image_size_details - either an array (with w/h attributes) or a string |
|
|
|
|
444
|
|
|
* |
445
|
|
|
* @throws RuntimeException |
446
|
|
|
*/ |
447
|
|
|
protected function getImageFilename(string $suggested_title, $image_size_details, UploadedFile $photo): string |
448
|
|
|
{ |
449
|
|
|
$base = $this->baseFilename($suggested_title); |
450
|
|
|
|
451
|
|
|
// $wh will be something like "-1200x300" |
452
|
|
|
$wh = $this->getDimensions($image_size_details); |
453
|
|
|
$ext = '.'.$photo->getClientOriginalExtension(); |
454
|
|
|
|
455
|
|
|
for ($i = 1; $i <= self::$availableFilenameAttempts; $i++) { |
456
|
|
|
// add suffix if $i>1 |
457
|
|
|
$suffix = $i > 1 ? '-'.Str::random(5) : ''; |
458
|
|
|
|
459
|
|
|
$attempt = Str::slug($base.$suffix.$wh).$ext; |
460
|
|
|
|
461
|
|
|
if (!$this::disk()->exists($this->imageDestinationPath().'/'.$attempt)) { |
462
|
|
|
return $attempt; |
463
|
|
|
} |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
// too many attempts... |
467
|
|
|
throw new RuntimeException("Unable to find a free filename after $i attempts - aborting now."); |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
protected function baseFilename(string $suggestedTitle): string |
471
|
|
|
{ |
472
|
|
|
$base = substr($suggestedTitle, 0, 100); |
473
|
|
|
|
474
|
|
|
return $base ?: 'image-'.Str::random(5); |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Get the width and height as a string, with x between them |
479
|
|
|
* (123x456). |
480
|
|
|
* |
481
|
|
|
* It will always be prepended with '-' |
482
|
|
|
* |
483
|
|
|
* Example return value: -123x456 |
484
|
|
|
* |
485
|
|
|
* $image_size_details should either be an array with two items ([$width, $height]), |
486
|
|
|
* or a string. |
487
|
|
|
* |
488
|
|
|
* If an array is given: |
489
|
|
|
* getWhForFilename([123,456]) it will return "-123x456" |
490
|
|
|
* |
491
|
|
|
* If a string is given: |
492
|
|
|
* getWhForFilename("some string") it will return -some-string". (max len: 30) |
493
|
|
|
* |
494
|
|
|
* @param array|string $imageSize |
495
|
|
|
* |
496
|
|
|
* @throws RuntimeException |
497
|
|
|
*/ |
498
|
|
|
protected function getDimensions($imageSize): string |
499
|
|
|
{ |
500
|
|
|
if (is_array($imageSize)) { |
501
|
|
|
return '-'.$imageSize['w'].'x'.$imageSize['h']; |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
return '-'.Str::slug(substr($imageSize, 0, 30)); |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* @deprecated - use getDimensions() |
509
|
|
|
*/ |
510
|
|
|
protected function getWhForFilename($image_size_details) |
511
|
|
|
{ |
512
|
|
|
return $this->getDimensions($image_size_details); |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* @throws RuntimeException |
517
|
|
|
*/ |
518
|
|
|
protected function imageDestinationPath(): string |
519
|
|
|
{ |
520
|
|
|
return config('blogetc.blog_upload_dir'); |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* Store new image upload meta data in database. |
525
|
|
|
*/ |
526
|
|
|
protected function storeInDatabase( |
527
|
|
|
?int $blogPostID, |
528
|
|
|
string $imageTitle, |
529
|
|
|
string $source, |
530
|
|
|
?int $uploaderID, |
531
|
|
|
array $uploadedImages |
532
|
|
|
): UploadedPhoto { |
533
|
|
|
// store the image upload. |
534
|
|
|
return $this->repository->create([ |
535
|
|
|
'blog_etc_post_id' => $blogPostID, |
536
|
|
|
'image_title' => $imageTitle, |
537
|
|
|
'source' => $source, |
538
|
|
|
'uploader_id' => $uploaderID, |
539
|
|
|
'uploaded_images' => $uploadedImages, |
540
|
|
|
]); |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
// /** |
544
|
|
|
// * Process any uploaded images (for featured image). |
545
|
|
|
// * |
546
|
|
|
// * @throws Exception |
547
|
|
|
// * |
548
|
|
|
// * @todo - next full release, tidy this up! |
549
|
|
|
// */ |
550
|
|
|
// public function processFeaturedUpload(PostRequest $request, Post $new_blog_post): ?array |
551
|
|
|
// { |
552
|
|
|
// if (! config('blogetc.image_upload_enabled')) { |
553
|
|
|
// // image upload was disabled |
554
|
|
|
// return null; |
555
|
|
|
// } |
556
|
|
|
// |
557
|
|
|
// $newSizes = []; |
558
|
|
|
// $this->increaseMemoryLimit(); |
559
|
|
|
// |
560
|
|
|
// // to save in db later |
561
|
|
|
// $uploaded_image_details = []; |
562
|
|
|
// |
563
|
|
|
// $enabledImageSizes = collect((array) config('blogetc.image_sizes')) |
564
|
|
|
// ->filter(function ($size) { |
565
|
|
|
// return ! empty($size['enabled']); |
566
|
|
|
// }); |
567
|
|
|
// |
568
|
|
|
// foreach ($enabledImageSizes as $size => $image_size_details) { |
569
|
|
|
// $photo = $request->getImageSize($size); |
570
|
|
|
// |
571
|
|
|
// if (! $photo) { |
572
|
|
|
// continue; |
573
|
|
|
// } |
574
|
|
|
// |
575
|
|
|
// $uploaded_image = $this->uploadAndResize( |
576
|
|
|
// $new_blog_post, |
577
|
|
|
// $new_blog_post->title, |
578
|
|
|
// $image_size_details, |
579
|
|
|
// $photo |
580
|
|
|
// ); |
581
|
|
|
// |
582
|
|
|
// $newSizes[$size] = $uploaded_image['filename']; |
583
|
|
|
// |
584
|
|
|
// $uploaded_image_details[$size] = $uploaded_image; |
585
|
|
|
// } |
586
|
|
|
// |
587
|
|
|
// // store the image upload. |
588
|
|
|
// if (empty($newSizes)) { |
589
|
|
|
// // Nothing to do if there were no sizes in config. |
590
|
|
|
// return null; |
591
|
|
|
// } |
592
|
|
|
// |
593
|
|
|
// // todo: link this to the blogetc_post row. |
594
|
|
|
// $this->storeInDatabase( |
595
|
|
|
// $new_blog_post->id, |
596
|
|
|
// $new_blog_post->title, |
597
|
|
|
// UploadedPhoto::SOURCE_FEATURED_IMAGE, |
598
|
|
|
// Auth::id(), |
599
|
|
|
// $uploaded_image_details |
600
|
|
|
// ); |
601
|
|
|
// |
602
|
|
|
// return $newSizes; |
603
|
|
|
// } |
604
|
|
|
|
605
|
|
|
/** |
606
|
|
|
* Legacy function, will be refactored soon. |
607
|
|
|
* |
608
|
|
|
* @param $blogPostId |
609
|
|
|
* |
610
|
|
|
* @return mixed |
611
|
|
|
*/ |
612
|
|
|
public function legacyDestroyPost(/* @scrutinizer ignore-unused */ DeleteBlogEtcPostRequest $request, $blogPostId) |
613
|
|
|
{ |
614
|
|
|
$post = Post::findOrFail($blogPostId); |
615
|
|
|
event(new BlogPostWillBeDeleted($post)); |
616
|
|
|
|
617
|
|
|
$post->delete(); |
618
|
|
|
|
619
|
|
|
// todo - delete the featured images? |
620
|
|
|
// At the moment it just issues a warning saying the images are still on the server. |
621
|
|
|
|
622
|
|
|
return $post; |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
public function deletePostImage(Post $post):array{ |
626
|
|
|
$deletedImageSizes = []; |
627
|
|
|
foreach(array_keys(config('blogetc.image_sizes')) as $size) { |
628
|
|
|
$imageFilename = $post->$size; |
629
|
|
|
$path = $this->image_destination_path() .'/'. $imageFilename; |
630
|
|
|
|
631
|
|
|
if($imageFilename && file_exists($path) ){ |
632
|
|
|
unlink($path); |
633
|
|
|
$deletedImageSizes[] = $size; |
634
|
|
|
} |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
return $deletedImageSizes; |
638
|
|
|
} |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
|