Files
WMS/Modules/Helpdesk/Services/AttachmentService.php
T

104 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\Helpdesk\Services;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Modules\Helpdesk\Models\Attachment;
use Modules\Helpdesk\Models\Comment;
use Modules\Helpdesk\Models\Ticket;
final class AttachmentService
{
/**
* Store multiple Helpdesk attachments against a ticket or comment.
*
* Livewire create/comment forms pass TemporaryUploadedFile instances, while
* controller endpoints pass Symfony/Laravel UploadedFile instances. Both
* are supported here so uploads are never silently skipped on ticket create.
*
* @param array<int|string, mixed> $files
*/
public function storeMany(Ticket $ticket, array $files, int $userId, ?Comment $comment = null): void
{
foreach ($files as $file) {
if (! $this->isSupportedUpload($file)) {
continue;
}
$disk = (string) config('helpdesk.disk', 'public');
$originalName = $this->originalName($file);
$mimeType = $this->mimeType($file);
$size = $this->size($file);
$path = $file->store('tickets/' . $ticket->id, $disk);
if (! is_string($path) || $path === '') {
continue;
}
if ($size === 0) {
$size = (int) Storage::disk($disk)->size($path);
}
Attachment::query()->create([
'ticket_id' => $ticket->id,
'comment_id' => $comment?->id,
'user_id' => $userId,
'disk' => $disk,
'path' => $path,
'original_name' => $originalName,
'mime_type' => $mimeType,
'size' => $size,
]);
}
}
/**
* Delete a stored attachment and its backing file.
*/
public function delete(Attachment $attachment): void
{
Storage::disk($attachment->disk)->delete($attachment->path);
$attachment->delete();
}
/**
* Determine whether the value is a storeable uploaded file.
*/
private function isSupportedUpload(mixed $file): bool
{
if ($file instanceof TemporaryUploadedFile) {
return true;
}
return $file instanceof UploadedFile && $file->isValid();
}
/**
* Return the uploaded file's original client filename.
*/
private function originalName(mixed $file): string
{
return (string) $file->getClientOriginalName();
}
/**
* Return the uploaded file's reported mime type.
*/
private function mimeType(mixed $file): string
{
return (string) ($file->getClientMimeType() ?: $file->getMimeType() ?: 'application/octet-stream');
}
/**
* Return the uploaded file's byte size.
*/
private function size(mixed $file): int
{
return (int) ($file->getSize() ?: 0);
}
}