0

I have a user row with employee's details and $image has multiple files stored in database. I want to download each file. so far I can only download a single file stored in $image

here is myview.blade.php

<input type="file" name="image[]" class="form-control" value="{{ $employee['image'] }}" multiple>
 <a href="{{ url('/people/employees/download/' . $employee['image']) }}">{{$employee['image']}}</a>

my route.php

Route::get('/people/employees/upload/{id}', 'EmplController@upload');
Route::get('/people/employees/download/{image}', 'EmplController@download');

my controller.php

public function test(Request $request, $id) {
    
    $employee = User::find($id);

    if($request->hasfile('image')){
        $files = [];
        foreach ($request->image as $image) {
            $path = $image->getClientOriginalName();
            $filename = time() . '-' . $path;
            $files[] = $filename;
            $image->storeAs('employees', $employee->id . '/' . $filename);
            $image->move(public_path('employees'),$filename);
        }

        $files = explode(",", $files[0]);
    }

    $employee->image = $employee->image  .  $files[0];
    $employee->save();  
}

public function download($image){
    $employee = User::find($image);
    $filename = $image;
    $filepath = public_path('employees/' . $filename);

    return response()->download($filepath);
}

when I do a print_r function while uploading multiple files it picks one file?

Array ( [0] => 1596838646-logo.jpg )

I want to download multiple files displayed on myview.blade.

SEYED BABAK ASHRAFI
  • 4,093
  • 4
  • 22
  • 32
mr_ceejay
  • 21
  • 7

2 Answers2

0

I believe that what you asking is to download multiple files over the same request using HTTP protocol and that is not possible as it is explained in this answer:

Laravel Download Multiple Files

What I would suggest is to make a client-side function that can make multiple calls to the download method for each specific file.

E.g based on your question, It could be something like:

HTML:

<a onclick='return downloadFiles()'>{{$employee['image']}}</a>

JS:

function downloadFiles(e) {
    e.preventDefault();
    for (img of IMAGES_FROM_THE_BACK) { 
        setTimeout(() => {
            window.open(`/people/employees/download/${img}`);
        }, 300);
    }
});

Please note that you would need to pass your images to an array or object from the back to the front end where you've your HTML.

Dharman
  • 30,962
  • 25
  • 85
  • 135
JGuarate
  • 378
  • 3
  • 9
  • Ok, can I make a zip folder with a link@jguarate – mr_ceejay Aug 07 '20 at 22:57
  • 1
    Yes, sure you can use the same download route (/people/employees/download/) -> (public function download($image){) and change your method implementation like it is explained on the https://stackoverflow.com/questions/1754352/download-multiple-files-as-a-zip-file-using-php answer. You just need to use the PHP ZipClass file. E.g: `new \ZipArchive();` – JGuarate Aug 07 '20 at 23:49
  • Zipping is the way to go here, @JGuarate maybe you can propose another answer? – Christophe Hubert Aug 08 '20 at 01:45
  • Yeap. Like I said, Zipping or a front-end implementation to trigger the browser with multiple downloads whatever suits your business needs better. Oh, and If the seconds one considers that multiple browsers with prompt the user for permissions to download multiple files. – JGuarate Aug 08 '20 at 01:55
0

As the subop from above said It's impossible, because HTTP doesn't support multiple files download. And one of solution is to open connection per file to download, but in my opinion more elegant would be files zipping which has them all.

PHP provides solution for that and it's ZipArchive

After, you ZIP all files, write on disk in tmp directory, and send a stream response using your file location. After php close connection, you can use Laravel Terminate Middleware/Callback and delete that archive to flush space on your disk.

Simple example in plain PHP taken from link above.

$files = array('image.jpeg','text.txt','music.wav');
$zipname = 'enter_any_name_for_the_zipped_file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
  $zip->addFile($file);
}
$zip->close();

///Then download the zipped file.
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
Maciej Król
  • 382
  • 1
  • 8