Skip to content

Commit

Permalink
Merge pull request #122 from InternetMarketingUniversiteit/patch-1
Browse files Browse the repository at this point in the history
Support downloads in multi server setup or serverless
  • Loading branch information
patrickbrouwers authored Aug 16, 2021
2 parents c6f9441 + 5ec6a7c commit 9912e8d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
38 changes: 34 additions & 4 deletions src/Actions/DownloadExcel.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Maatwebsite\LaravelNovaExcel\Actions;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Http\Requests\ActionRequest;
use Maatwebsite\Excel\Facades\Excel;
Expand All @@ -28,6 +29,10 @@ public function name()
*/
public function handle(ActionRequest $request, Action $exportable): array
{
if (config('excel.temporary_files.remote_disk')) {
return $this->handleRemoteDisk($request, $exportable);
}

$response = Excel::download(
$exportable,
$this->getFilename(),
Expand All @@ -43,20 +48,45 @@ public function handle(ActionRequest $request, Action $exportable): array
return \is_callable($this->onSuccess)
? ($this->onSuccess)($request, $response)
: Action::download(
$this->getDownloadUrl($response),
$this->getDownloadUrl($response->getFile()->getPathname()),
$this->getFilename()
);
}

/**
* @param ActionRequest $request
* @param Action $exportable
*
* @return array
*/
public function handleRemoteDisk(ActionRequest $request, Action $exportable): array
{
$temporaryFilePath = config('excel.temporary_files.remote_prefix') . 'laravel-excel-' . Str::random(32) . '.' . $this->getDefaultExtension();
$isStored = Excel::store($exportable, $temporaryFilePath, config('excel.temporary_files.remote_disk'), $this->getWriterType());

if (!$isStored) {
return \is_callable($this->onFailure)
? ($this->onFailure)($request, null)
: Action::danger(__('Resource could not be exported.'));
}

return \is_callable($this->onSuccess)
? ($this->onSuccess)($request, $temporaryFilePath)
: Action::download(
$this->getDownloadUrl($temporaryFilePath),
$this->getFilename()
);
}

/**
* @param BinaryFileResponse $response
* @param string $filePath
*
* @return string
*/
protected function getDownloadUrl(BinaryFileResponse $response): string
protected function getDownloadUrl(string $filePath): string
{
return URL::temporarySignedRoute('laravel-nova-excel.download', now()->addMinutes(1), [
'path' => encrypt($response->getFile()->getPathname()),
'path' => encrypt($filePath),
'filename' => $this->getFilename(),
]);
}
Expand Down
26 changes: 19 additions & 7 deletions src/Http/Controllers/ExcelController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Routing\ResponseFactory;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;

class ExcelController extends Controller
{
Expand All @@ -17,19 +18,30 @@ class ExcelController extends Controller
* @param Request $request
* @param ResponseFactory $response
*
* @return BinaryFileResponse
* @return Response
* @throws ValidationException
*/
public function download(Request $request, ResponseFactory $response): BinaryFileResponse
public function download(Request $request, ResponseFactory $response): Response
{
$data = $this->validate($request, [
'path' => 'required',
'filename' => 'required',
]);

return $response->download(
decrypt($data['path']),
$data['filename']
)->deleteFileAfterSend($shouldDelete = true);
$decryptedPath = decrypt($data['path']);

if (config('excel.temporary_files.remote_disk')) {
app()->terminating(function () use ($decryptedPath) {
Storage::disk(config('excel.temporary_files.remote_disk'))->delete($decryptedPath);
});

return Storage::disk(config('excel.temporary_files.remote_disk'))
->download($decryptedPath, $data['filename']);
} else {
return $response->download(
decrypt($data['path']),
$data['filename']
)->deleteFileAfterSend($shouldDelete = true);
}
}
}

0 comments on commit 9912e8d

Please sign in to comment.