@@ -11,33 +11,39 @@ class MediaController extends Controller
11
11
{
12
12
use OpsTrait;
13
13
14
+ // main
14
15
protected $ fileSystem ;
15
16
protected $ storageDisk ;
16
17
protected $ ignoreFiles ;
17
18
protected $ fileChars ;
18
19
protected $ folderChars ;
19
20
protected $ sanitizedText ;
20
- protected $ unallowed_mimes ;
21
+ protected $ unallowedMimes ;
21
22
protected $ LMF ;
22
23
23
- protected $ locked_files_list ;
24
- protected $ disks ;
24
+ // extra
25
+ protected $ storageDiskInfo ;
26
+ protected $ lockedList ;
27
+ protected $ cacheStore ;
28
+ protected $ db ;
25
29
26
30
public function __construct ()
27
31
{
28
32
$ config = config ('mediaManager ' );
29
33
30
- $ this ->fileSystem = array_get ($ config , 'storage_disk ' );
31
- $ this ->storageDisk = app ('filesystem ' )->disk ($ this ->fileSystem );
32
- $ this ->ignoreFiles = array_get ($ config , 'ignore_files ' );
33
- $ this ->fileChars = array_get ($ config , 'allowed_fileNames_chars ' );
34
- $ this ->folderChars = array_get ($ config , 'allowed_folderNames_chars ' );
35
- $ this ->sanitizedText = array_get ($ config , 'sanitized_text ' );
36
- $ this ->unallowed_mimes = array_get ($ config , 'unallowed_mimes ' );
37
- $ this ->LMF = array_get ($ config , 'last_modified_format ' );
38
-
39
- $ this ->locked_files_list = array_get ($ config , 'locked_files_list ' );
40
- $ this ->disks = config ("filesystems.disks. {$ this ->fileSystem }" );
34
+ $ this ->fileSystem = array_get ($ config , 'storage_disk ' );
35
+ $ this ->storageDisk = app ('filesystem ' )->disk ($ this ->fileSystem );
36
+ $ this ->ignoreFiles = array_get ($ config , 'ignore_files ' );
37
+ $ this ->fileChars = array_get ($ config , 'allowed_fileNames_chars ' );
38
+ $ this ->folderChars = array_get ($ config , 'allowed_folderNames_chars ' );
39
+ $ this ->sanitizedText = array_get ($ config , 'sanitized_text ' );
40
+ $ this ->unallowedMimes = array_get ($ config , 'unallowed_mimes ' );
41
+ $ this ->LMF = array_get ($ config , 'last_modified_format ' );
42
+
43
+ $ this ->db = app ('db ' )->connection ('mediamanager ' );
44
+ $ this ->lockedList = $ this ->db ->table ('locked ' )->pluck ('path ' );
45
+ $ this ->storageDiskInfo = config ("filesystems.disks. {$ this ->fileSystem }" );
46
+ $ this ->cacheStore = app ('cache ' )->store ('mediamanager ' );
41
47
}
42
48
43
49
/**
@@ -68,7 +74,7 @@ public function get_files(Request $request)
68
74
}
69
75
70
76
return response ()->json ([
71
- 'locked ' => app ( ' db ' )-> connection ( ' mediamanager ' )-> table ( ' locked ' )-> pluck ( ' path ' ) ,
77
+ 'locked ' => $ this -> lockedList ,
72
78
'files ' => [
73
79
'path ' => $ folder ,
74
80
'items ' => $ this ->getData ($ folder ),
@@ -121,7 +127,7 @@ public function upload(Request $request)
121
127
122
128
try {
123
129
// check for mime type
124
- if (str_contains ($ file_type , $ this ->unallowed_mimes )) {
130
+ if (str_contains ($ file_type , $ this ->unallowedMimes )) {
125
131
throw new Exception (trans ('MediaManager::messages.not_allowed_file_ext ' , ['attr ' =>$ file_type ]));
126
132
}
127
133
@@ -291,7 +297,7 @@ public function move_file(Request $request)
291
297
'size ' => $ file_size ,
292
298
];
293
299
} else {
294
- $ exc = array_get ($ this ->disks , 'root ' )
300
+ $ exc = array_get ($ this ->storageDiskInfo , 'root ' )
295
301
? trans ('MediaManager::messages.error_moving ' )
296
302
: trans ('MediaManager::messages.error_moving_cloud ' );
297
303
@@ -334,7 +340,7 @@ public function move_file(Request $request)
334
340
} else {
335
341
$ exc = trans ('MediaManager::messages.error_moving ' );
336
342
337
- if ('folder ' == $ one ['type ' ] && !array_get ($ this ->disks , 'root ' )) {
343
+ if ('folder ' == $ one ['type ' ] && !array_get ($ this ->storageDiskInfo , 'root ' )) {
338
344
$ exc = trans ('MediaManager::messages.error_moving_cloud ' );
339
345
}
340
346
@@ -410,7 +416,7 @@ public function lock_file(Request $request)
410
416
{
411
417
$ path = $ request ->path ;
412
418
$ state = $ request ->state ;
413
- $ db = app ( ' db ' )-> connection ( ' mediamanager ' ) ->table ('locked ' );
419
+ $ db = $ this -> db ->table ('locked ' );
414
420
415
421
'locked ' == $ state
416
422
? $ db ->insert (['path ' =>$ path ])
@@ -420,60 +426,136 @@ public function lock_file(Request $request)
420
426
}
421
427
422
428
/**
423
- * zip folders.
424
- *
425
- * @param Request $request [description]
426
- *
427
- * @return [type] [description]
429
+ * zip ops.
428
430
*/
429
431
public function folder_download (Request $ request )
430
432
{
431
- $ name = $ request ->name ;
432
- $ dir = "{$ request ->folders }/ $ name " ;
433
+ return $ this ->download (
434
+ $ request ->name ,
435
+ $ this ->storageDisk ->allFiles ("{$ request ->folders }/ $ request ->name " ),
436
+ 'folder '
437
+ );
438
+ }
439
+
440
+ public function files_download (Request $ request )
441
+ {
442
+ return $ this ->download (
443
+ $ request ->name . '-files ' ,
444
+ json_decode ($ request ->list , true ),
445
+ 'files '
446
+ );
447
+ }
448
+
449
+ protected function download ($ name , $ list , $ type )
450
+ {
451
+ // track changes
452
+ $ counter = 100 / count ($ list );
453
+ $ store = $ this ->cacheStore ;
454
+ $ cache_name = $ name ;
455
+ $ store ->forever ("$ cache_name.progress " , 0 );
433
456
434
- return response ()->stream (function () use ($ name , $ dir ) {
457
+ return response ()->stream (function () use ($ name , $ list , $ type , $ counter , $ store , $ cache_name ) {
435
458
$ zip = new ZipStream ("$ name.zip " , [
436
459
'content_type ' => 'application/octet-stream ' ,
437
460
]);
438
461
439
- foreach ($ this ->storageDisk ->allFiles ($ dir ) as $ file ) {
440
- if ($ streamRead = $ this ->storageDisk ->readStream ($ file )) {
441
- $ zip ->addFileFromStream (pathinfo ($ file , PATHINFO_BASENAME ), $ streamRead );
462
+ foreach ($ list as $ file ) {
463
+ if ('folder ' == $ type ) {
464
+ $ file_name = pathinfo ($ file , PATHINFO_BASENAME );
465
+ $ streamRead = $ this ->storageDisk ->readStream ($ file );
466
+ } else {
467
+ $ file_name = $ file ['name ' ];
468
+ $ streamRead = @fopen ($ file ['path ' ], 'r ' );
469
+ }
470
+
471
+ if ($ streamRead ) {
472
+ $ store ->increment ("$ cache_name.progress " , round ($ counter , 2 ));
473
+ $ zip ->addFileFromStream ($ file_name , $ streamRead );
442
474
} else {
443
- die ('Could not open stream for reading ' );
475
+ $ store ->forever ("$ cache_name.abort " , $ file_name );
476
+ die ();
444
477
}
445
478
}
446
479
480
+ $ store ->forever ("$ cache_name.done " , true );
447
481
$ zip ->finish ();
448
482
});
449
483
}
450
484
451
485
/**
452
- * zip files.
453
- *
454
- * @param Request $request [description]
455
- *
456
- * @return [type] [description]
486
+ * zip progress update.
457
487
*/
458
- public function files_download (Request $ request )
488
+ public function zip_progress (Request $ request )
459
489
{
460
- $ name = $ request ->name ;
461
- $ list = json_decode ($ request ->list , true );
490
+ // stop execution
491
+ $ start = time ();
492
+ $ maxExecution = ini_get ('max_execution_time ' );
493
+ $ sleep = array_get ($ this ->storageDiskInfo , 'root ' ) ? 0.5 : 1.5 ;
494
+ $ close = false ;
495
+
496
+ // params
497
+ $ id = $ request ->header ('last-event-id ' );
498
+ $ name = $ request ->name ;
499
+
500
+ // get changes
501
+ $ store = $ this ->cacheStore ;
502
+ $ cache_name = $ name ;
503
+
504
+ return response ()->stream (function () use ($ start , $ maxExecution , $ close , $ sleep , $ store , $ cache_name ) {
505
+ while (!$ close ) {
506
+ // progress
507
+ $ this ->es_msg ($ store ->get ("$ cache_name.progress " ), 'progress ' );
508
+
509
+ // avoid server crash
510
+ if (time () >= $ start + $ maxExecution ) {
511
+ $ close = true ;
512
+ $ this ->es_msg (null , 'exit ' );
513
+ $ this ->clearZipCache ($ store , $ cache_name );
514
+ }
462
515
463
- return response ()->stream (function () use ($ name , $ list ) {
464
- $ zip = new ZipStream ("$ name.zip " , [
465
- 'content_type ' => 'application/octet-stream ' ,
466
- ]);
516
+ // abort
517
+ if ($ store ->has ("$ cache_name.abort " )) {
518
+ $ close = true ;
519
+ $ this ->es_msg ('Could not open " ' . $ store ->get ("$ cache_name.abort " ) . '" stream for reading. ' , 'abort ' );
520
+ $ this ->clearZipCache ($ store , $ cache_name );
521
+ }
467
522
468
- foreach ($ list as $ file ) {
469
- if ($ streamRead = fopen ($ file ['path ' ], 'r ' )) {
470
- $ zip ->addFileFromStream ($ file ['name ' ], $ streamRead );
471
- } else {
472
- die ('Could not open stream for reading ' );
523
+ // done
524
+ if ($ store ->has ("$ cache_name.done " )) {
525
+ $ close = true ;
526
+ $ this ->es_msg (100 , 'progress ' );
527
+ $ this ->es_msg ('All Done ' , 'done ' );
528
+ $ this ->clearZipCache ($ store , $ cache_name );
529
+ }
530
+
531
+ ob_flush ();
532
+ flush ();
533
+
534
+ // don't wait unnecessary
535
+ if (!$ close ) {
536
+ sleep ($ sleep );
473
537
}
474
538
}
539
+ }, 200 , [
540
+ 'Content-Type ' => 'text/event-stream ' , // needed for SSE to work
541
+ 'Cache-Control ' => 'no-cache ' , // make sure we dont cache this response
542
+ 'X-Accel-Buffering ' => 'no ' , // needed for while loop to work
543
+ 'Access-Control-Allow-Origin ' => config ('app.url ' ), // for cors
544
+ 'Access-Control-Expose-Headers ' => '* ' , // for cors
545
+ 'Access-Control-Allow-Credentials ' => true , // for cors
546
+ ]);
547
+ }
475
548
476
- $ zip ->finish ();
477
- });
549
+ protected function es_msg ($ data = null , $ event = null )
550
+ {
551
+ echo $ event ? "event: $ event \n" : ': ' ;
552
+ echo $ data ? 'data: ' . json_encode (['response ' => $ data ]) . "\n\n" : ': ' ;
553
+ }
554
+
555
+ protected function clearZipCache ($ store , $ item )
556
+ {
557
+ $ store ->forget ("$ item.progress " );
558
+ $ store ->forget ("$ item.done " );
559
+ $ store ->forget ("$ item.abort " );
478
560
}
479
561
}
0 commit comments