55 lines
1.7 KiB
PHP
55 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Http\Controllers;
|
|
|
|
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Modules\Helpdesk\Models\Ticket;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
final class AttachmentDownloadController extends Controller
|
|
{
|
|
/**
|
|
* Download a ticket attachment through Laravel storage instead of a public URL.
|
|
*
|
|
* This avoids broken public storage links and keeps ticket authorization enforced.
|
|
*
|
|
* @throws FileNotFoundException
|
|
*/
|
|
public function __invoke(int $attachment): StreamedResponse|RedirectResponse
|
|
{
|
|
abort_unless(Schema::hasTable('helpdesk_attachments'), 404);
|
|
|
|
$row = DB::table('helpdesk_attachments')->where('id', $attachment)->first();
|
|
|
|
abort_if($row === null, 404);
|
|
|
|
$ticketId = $row->ticket_id ?? null;
|
|
|
|
if ($ticketId !== null) {
|
|
$ticket = Ticket::query()->findOrFail((int) $ticketId);
|
|
Gate::authorize('view', $ticket);
|
|
}
|
|
|
|
$disk = (string) ($row->disk ?? 'public');
|
|
$path = (string) ($row->path ?? $row->file_path ?? $row->stored_path ?? '');
|
|
$name = (string) ($row->original_name
|
|
?? $row->original_filename
|
|
?? $row->file_name
|
|
?? $row->filename
|
|
?? basename($path));
|
|
|
|
abort_if($path === '', 404);
|
|
abort_unless(Storage::disk($disk)->exists($path), 404);
|
|
|
|
return Storage::disk($disk)->download($path, $name);
|
|
}
|
|
}
|