@@ -43,16 +43,22 @@ public static function get_file_url( string $key ): string {
43
43
* @param string $existing_key
44
44
* @return false|mixed
45
45
*/
46
- public static function upload_file ( string $ key_prefix = '' , array $ upload = [], string $ existing_key = '' ){
46
+ public static function upload_file ( string $ key_prefix = '' , array $ upload = [], string $ existing_key = '' , array $ args = [] ){
47
47
$ key_prefix = trailingslashit ( $ key_prefix );
48
48
$ connection = self ::get_connection ();
49
- $ args = [
49
+ $ merged_args = array_merge ( $ args , [
50
50
'auto_generate_key ' => empty ( $ existing_key ),
51
51
'include_extension ' => empty ( $ existing_key ),
52
- 'default_key ' => $ existing_key
53
- ];
52
+ 'default_key ' => $ existing_key ,
53
+ 'auto_generate_thumbnails ' => in_array ( strtolower ( trim ( $ upload ['type ' ] ?? '' ) ), [
54
+ 'image/gif ' ,
55
+ 'image/jpeg ' ,
56
+ 'image/png '
57
+ ] ),
58
+ 'thumbnails_desired_width ' => 32 // Heights are automatically calculated, based on specified width.
59
+ ] );
54
60
if ( !empty ( $ connection ) ) {
55
- return dt_storage_connections_obj_upload ( null , $ connection ->id , $ key_prefix , $ upload , $ args );
61
+ return dt_storage_connections_obj_upload ( null , $ connection ->id , $ key_prefix , $ upload , $ merged_args );
56
62
}
57
63
return false ;
58
64
}
@@ -184,7 +190,6 @@ function dt_storage_connections_obj_upload( $response, $storage_connection_id, $
184
190
185
191
$ s3 = null ;
186
192
$ response = true ;
187
- $ upload_id = null ;
188
193
$ bucket = $ config ['bucket ' ];
189
194
190
195
// Generate complete file key name to be used moving forward.
@@ -206,84 +211,152 @@ function dt_storage_connections_obj_upload( $response, $storage_connection_id, $
206
211
'endpoint ' => $ endpoint
207
212
] );
208
213
214
+ // First, upload original file.
215
+ $ uploaded_key = dt_storage_connections_obj_upload_s3 ( $ s3 , $ bucket , $ key_name , $ upload );
216
+
217
+ // Next, if specified, generate and upload a corresponding thumbnail.
218
+ $ uploaded_thumbnail_key = null ;
219
+ if ( isset ( $ args ['auto_generate_thumbnails ' ] ) && $ args ['auto_generate_thumbnails ' ] ) {
220
+ $ thumbnail = Disciple_Tools_Storage_API::generate_image_thumbnail ( $ upload ['tmp_name ' ], $ upload ['type ' ] ?? '' , $ args ['thumbnails_desired_width ' ] ?? 32 );
221
+ if ( !empty ( $ thumbnail ) ) {
222
+
223
+ // Generate temp file to function as a reference point for generated thumbnail.
224
+ $ tmp_image = tmpfile ();
225
+ $ tmp_image_metadata = stream_get_meta_data ( $ tmp_image );
226
+
227
+ // Next, populate temp file, accordingly, by image content type.
228
+ $ thumbnail_tmp_name = null ;
229
+ switch ( strtolower ( trim ( $ upload ['type ' ] ?? '' ) ) ) {
230
+ case 'image/gif ' :
231
+ if ( imagegif ( $ thumbnail , $ tmp_image ) ) {
232
+ $ thumbnail_tmp_name = $ tmp_image_metadata ['uri ' ];
233
+ }
234
+ break ;
235
+ case 'image/jpeg ' :
236
+ if ( imagejpeg ( $ thumbnail , $ tmp_image ) ) {
237
+ $ thumbnail_tmp_name = $ tmp_image_metadata ['uri ' ];
238
+ }
239
+ break ;
240
+ case 'image/png ' :
241
+ if ( imagepng ( $ thumbnail , $ tmp_image ) ) {
242
+ $ thumbnail_tmp_name = $ tmp_image_metadata ['uri ' ];
243
+ }
244
+ break ;
245
+ default :
246
+ break ;
247
+ }
248
+
249
+ // If we have a valid thumbnail temp file, proceed with upload attempt.
250
+ if ( !empty ( $ thumbnail_tmp_name ) ) {
251
+
252
+ // Adjust reference to temp file, for recently generated thumbnail.
253
+ $ upload ['tmp_name ' ] = $ thumbnail_tmp_name ;
254
+
255
+ // Fetch thumbnail sizing info, to be used to generate suffix for key_name.
256
+ $ thumbnail_size = getimagesize ( $ thumbnail_tmp_name );
257
+ if ( !empty ( $ thumbnail_size ) ) {
258
+ $ thumbnail_key_name = $ key_name . '. ' . $ thumbnail_size [0 ] . 'x ' . $ thumbnail_size [1 ];
259
+ $ uploaded_thumbnail_key = dt_storage_connections_obj_upload_s3 ( $ s3 , $ bucket , $ thumbnail_key_name , $ upload );
260
+ }
261
+ }
262
+ }
263
+ }
209
264
210
- // Upload file in parts, to better manage memory leaks.
211
- $ result = $ s3 ->createMultipartUpload ( [
212
- 'Bucket ' => $ bucket ,
213
- 'Key ' => $ key_name ,
214
- // 'StorageClass' => 'REDUCED_REDUNDANCY', // NB: Currently not supported by Backblaze
215
- // 'ACL' => 'public-read', // NB: Currently not supported by Backblaze
216
- 'ContentType ' => $ upload ['type ' ] ?? '' ,
217
- 'Metadata ' => []
218
- ] );
219
- $ upload_id = $ result ['UploadId ' ];
220
-
265
+ // Finally, capture valid uploaded keys.
266
+ $ response = [
267
+ 'uploaded_key ' => ! empty ( $ uploaded_key ) ? $ uploaded_key : null ,
268
+ 'uploaded_thumbnail_key ' => ! empty ( $ uploaded_thumbnail_key ) ? $ uploaded_thumbnail_key : null
269
+ ];
221
270
} catch ( Exception $ e ) {
222
271
$ response = false ;
223
272
}
273
+ }
274
+ break ;
275
+ default :
276
+ break ;
277
+ }
278
+ }
224
279
225
- // Ensure no previous upload exceptions have been encountered.
226
- if ( $ response !== false ) {
227
- $ parts = [];
228
-
229
- try {
230
-
231
- // Start to upload file in partial chunks.
232
- $ filename = $ upload ['tmp_name ' ] ?? '' ;
233
- $ file = fopen ( $ filename , 'r ' );
234
- $ part_number = 1 ;
235
- while ( !feof ( $ file ) ) {
236
- $ result = $ s3 ->uploadPart ( [
237
- 'Bucket ' => $ bucket ,
238
- 'Key ' => $ key_name ,
239
- 'UploadId ' => $ upload_id ,
240
- 'PartNumber ' => $ part_number ,
241
- 'Body ' => fread ( $ file , 5 * 1024 * 1024 ),
242
- ] );
243
-
244
- $ parts ['Parts ' ][$ part_number ] = [
245
- 'PartNumber ' => $ part_number ,
246
- 'ETag ' => $ result ['ETag ' ],
247
- ];
248
-
249
- // Increment part count and force garbage collection, to better manage memory.
250
- $ part_number ++;
251
- gc_collect_cycles ();
252
- }
253
- fclose ( $ file );
254
-
255
- } catch ( Exception $ e ) {
256
- $ response = false ;
257
- $ result = $ s3 ->abortMultipartUpload ( [
258
- 'Bucket ' => $ bucket ,
259
- 'Key ' => $ key_name ,
260
- 'UploadId ' => $ upload_id
261
- ] );
262
- }
280
+ return $ response ;
281
+ }
263
282
264
- // Ensure no previous upload exceptions have been encountered.
265
- if ( $ response !== false ) {
283
+ function dt_storage_connections_obj_upload_s3 ( $ s3 , $ bucket , $ key_name , $ upload ) {
284
+ $ response = null ;
285
+ $ upload_id = null ;
286
+
287
+ try {
288
+
289
+ // Upload file in parts, to better manage memory leaks.
290
+ $ result = $ s3 ->createMultipartUpload ( [
291
+ 'Bucket ' => $ bucket ,
292
+ 'Key ' => $ key_name ,
293
+ // 'StorageClass' => 'REDUCED_REDUNDANCY', // NB: Currently not supported by Backblaze
294
+ // 'ACL' => 'public-read', // NB: Currently not supported by Backblaze
295
+ 'ContentType ' => $ upload ['type ' ] ?? '' ,
296
+ 'Metadata ' => []
297
+ ] );
298
+ $ upload_id = $ result ['UploadId ' ];
299
+
300
+ } catch ( Exception $ e ) {
301
+ $ response = false ;
302
+ }
266
303
267
- try {
304
+ // Ensure no previous upload exceptions have been encountered.
305
+ if ( $ response !== false ) {
306
+ $ parts = [];
307
+
308
+ try {
309
+
310
+ // Start to upload file in partial chunks.
311
+ $ filename = $ upload ['tmp_name ' ] ?? '' ;
312
+ $ file = fopen ( $ filename , 'r ' );
313
+ $ part_number = 1 ;
314
+ while ( !feof ( $ file ) ) {
315
+ $ result = $ s3 ->uploadPart ( [
316
+ 'Bucket ' => $ bucket ,
317
+ 'Key ' => $ key_name ,
318
+ 'UploadId ' => $ upload_id ,
319
+ 'PartNumber ' => $ part_number ,
320
+ 'Body ' => fread ( $ file , 5 * 1024 * 1024 ),
321
+ ] );
322
+
323
+ $ parts ['Parts ' ][$ part_number ] = [
324
+ 'PartNumber ' => $ part_number ,
325
+ 'ETag ' => $ result ['ETag ' ],
326
+ ];
327
+
328
+ // Increment part count and force garbage collection, to better manage memory.
329
+ $ part_number ++;
330
+ gc_collect_cycles ();
331
+ }
332
+ fclose ( $ file );
333
+
334
+ } catch ( Exception $ e ) {
335
+ $ response = false ;
336
+ $ result = $ s3 ->abortMultipartUpload ( [
337
+ 'Bucket ' => $ bucket ,
338
+ 'Key ' => $ key_name ,
339
+ 'UploadId ' => $ upload_id
340
+ ] );
341
+ }
268
342
269
- // Complete the multipart upload.
270
- $ result = $ s3 ->completeMultipartUpload ( [
271
- 'Bucket ' => $ bucket ,
272
- 'Key ' => $ key_name ,
273
- 'UploadId ' => $ upload_id ,
274
- 'MultipartUpload ' => $ parts ,
275
- ] );
276
- $ response = $ result ['Key ' ] ?? false ;
343
+ // Ensure no previous upload exceptions have been encountered.
344
+ if ( $ response !== false ) {
277
345
278
- } catch ( Exception $ e ) {
279
- $ response = false ;
280
- }
281
- }
282
- }
283
- }
284
- break ;
285
- default :
286
- break ;
346
+ try {
347
+
348
+ // Complete the multipart upload.
349
+ $ result = $ s3 ->completeMultipartUpload ( [
350
+ 'Bucket ' => $ bucket ,
351
+ 'Key ' => $ key_name ,
352
+ 'UploadId ' => $ upload_id ,
353
+ 'MultipartUpload ' => $ parts ,
354
+ ] );
355
+ $ response = $ result ['Key ' ] ?? false ;
356
+
357
+ } catch ( Exception $ e ) {
358
+ $ response = false ;
359
+ }
287
360
}
288
361
}
289
362
0 commit comments