e0dfc3ec82
API CI/CD / Validate (composer + pint) (push) Successful in 3m15s
API CI/CD / Test (PHPUnit) (push) Failing after 5m4s
API CI/CD / Build frontend assets (push) Successful in 1m3s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
56 lines
1.4 KiB
PHP
56 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Expenses;
|
|
|
|
use App\Services\ApplicationUrlService;
|
|
use Illuminate\Http\UploadedFile;
|
|
|
|
class ExpenseReceiptService
|
|
{
|
|
private ApplicationUrlService $urls;
|
|
|
|
public function __construct(?ApplicationUrlService $urls = null)
|
|
{
|
|
$this->urls = $urls ?? app(ApplicationUrlService::class);
|
|
}
|
|
|
|
public function storeReceipt(UploadedFile $file): string
|
|
{
|
|
if (! $file->isValid()) {
|
|
throw new \InvalidArgumentException('Invalid receipt upload.');
|
|
}
|
|
|
|
$allowed = [
|
|
'image/jpeg' => 'jpg',
|
|
'image/png' => 'png',
|
|
'image/webp' => 'webp',
|
|
'application/pdf' => 'pdf',
|
|
];
|
|
|
|
$mime = strtolower((string) $file->getMimeType());
|
|
if (! isset($allowed[$mime])) {
|
|
throw new \InvalidArgumentException('Unsupported receipt file type.');
|
|
}
|
|
|
|
if ((int) $file->getSize() > 5 * 1024 * 1024) {
|
|
throw new \InvalidArgumentException('Receipt file too large. Max 5MB.');
|
|
}
|
|
|
|
$filename = bin2hex(random_bytes(16)).'.'.$allowed[$mime];
|
|
$file->storeAs('receipts', $filename);
|
|
|
|
return $filename;
|
|
}
|
|
|
|
public function receiptUrl(?string $filename): ?string
|
|
{
|
|
if (! $filename) {
|
|
return null;
|
|
}
|
|
|
|
$safe = basename(trim($filename));
|
|
|
|
return $safe !== '' ? url('receipts/'.$safe) : null;
|
|
}
|
|
}
|